2015-11-02 13 views
5

Ho una "colllenctions mongodb" e mi piacerebbe rimuovere le "stringhe vuote" con le chiavi da esso.Come posso rimuovere una stringa vuota da una collezione mongodb?

Da questo:

{ 
    "_id" : ObjectId("56323d975134a77adac312c5"), 
    "year" : "15", 
    "year_comment" : "", 
} 
{ 
    "_id" : ObjectId("56323d975134a77adac312c5"), 
    "year" : "", 
    "year_comment" : "asd", 
} 

Mi piacerebbe ottenere questo risultato:

{ 
    "_id" : ObjectId("56323d975134a77adac312c5"), 
    "year" : "15", 
} 
{ 
    "_id" : ObjectId("56323d975134a77adac312c5"), 
    "year_comment" : "asd", 
} 

Come potrei risolverlo?

risposta

2

Prova esecuzione seguente frammento di codice in guscio Mongo, che mette a nudo i campi con valori vuoti o nulli

var result=new Array(); 
db.getCollection('test').find({}).forEach(function(data) 
{ 
    for(var i in data) 
    { 
     if(data[i]==null || data[i]=='') 
     { 
     delete data[i] 
     } 
    } 
    result.push(data) 

}) 

print(tojson(result)) 
+0

Elimina solo gli elementi vuoti dalla prima riga, ma l'altro lasciato in essi sono luoghi. Sto ancora cercando di scoprire qual è il problema. La shell scrive questo: [oggetto oggetto], [oggetto oggetto], [oggetto oggetto] ... –

+0

Funziona con questa funzione: stampa (tojson (risultato)); Problema risolto. –

+0

@FerencStraub Lo snippet di codice sopra riportato funziona con stripping dei campi del valore nullo nel risultato –

3

Comincerebbe con ottenere un elenco distinto di tutte le chiavi della raccolta, utilizzare quelle chiavi come base della query e eseguire un aggiornamento collettivo ordinato utilizzando le operazioni dell'API di massa. La dichiarazione di aggiornamento utilizza l'operatore $unset per rimuovere i campi.

Il meccanismo per ottenere l'elenco delle chiavi distinte che è necessario assemblare la query è possibile tramite Map-Reduce. La seguente operazione MapReduce compilerà una raccolta separata con tutti i tasti come i valori _id:

mr = db.runCommand({ 
    "mapreduce": "my_collection", 
    "map" : function() { 
     for (var key in this) { emit(key, null); } 
    }, 
    "reduce" : function(key, stuff) { return null; }, 
    "out": "my_collection" + "_keys" 
}) 

per ottenere un elenco di tutti i tasti dinamici, eseguire distinti sulla raccolta risultante:

db[mr.result].distinct("_id") 
// prints ["_id", "year", "year_comment", ...] 

Ora dato l'elenco sopra, è possibile assemblare la query creando un oggetto che avrà le sue proprietà impostate all'interno di un ciclo. Normalmente la query avrà questa struttura:

var keysList = ["_id", "year", "year_comment"]; 
var query = keysList.reduce(function(obj, k) { 
     var q = {}; 
     q[k] = ""; 
     obj["$or"].push(q); 
     return obj; 
    }, { "$or": [] }); 
printjson(query); // prints {"$or":[{"_id":""},{"year":""},{"year_comment":""}]} 

È possibile quindi utilizzare il Bulk API (disponibile con MongoDB 2.6 e superiore) come un modo di razionalizzare gli aggiornamenti per migliorare le prestazioni con la query di cui sopra. In generale, si dovrebbe essere in grado di avere qualcosa a lavorare come:

var bulk = db.collection.initializeOrderedBulkOp(), 
    counter = 0, 
    query = {"$or":[{"_id":""},{"year":""},{"year_comment":""}]}, 
    keysList = ["_id", "year", "year_comment"]; 


db.collection.find(query).forEach(function(doc){ 
    var emptyKeys = keysList.filter(function(k) { // use filter to return an array of keys which have empty strings 
      return doc[k]===""; 
     }), 
     update = emptyKeys.reduce(function(obj, k) { // set the update object 
      obj[k] = ""; 
      return obj; 
     }, { }); 

    bulk.find({ "_id": doc._id }).updateOne({ 
     "$unset": update // use the $unset operator to remove the fields 
    }); 

    counter++; 
    if (counter % 1000 == 0) { 
     // Execute per 1000 operations and re-initialize every 1000 update statements 
     bulk.execute(); 
     bulk = db.collection.initializeOrderedBulkOp(); 
    } 
}) 
+1

grazie per la risposta. –

+0

@FerencStraub Nessun problema, felice di aiutare :) – chridam

0

Se è necessario aggiornare un singolo parametro vuoto o si preferisce fare parametro dal parametro, è possibile utilizzare l'mongo updateMany funzionalità:

db.comments.updateMany({year: ""}, { $unset : { year : 1 }}) 
Problemi correlati