2015-11-02 19 views
5

Ich habe ein "mongodb colllenctions" und ich möchte die "leeren Saiten" mit Schlüsseln davon entfernen.Wie kann ich leere Zeichenfolge aus einer Mongodb-Sammlung entfernen?

Daraus:

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

Ich möchte dieses Ergebnis gewinnen:

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

Wie könnte ich es lösen?

Antwort

2

Bitte versuchen Sie folgende Code-Schnipsel in Mongo Shell ausführen, die Felder mit leeren oder Null-Werte Streifen

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

Es löscht nur die leeren Elemente aus der ersten Zeile, aber die anderen links in ihnen sind Orte. Ich versuche immer noch herauszufinden, was das Problem ist. Die Shell schreibt dies: [Objekt Objekt], [Objekt Objekt], [Objekt Objekt] ... –

+0

Funktioniert mit dieser Funktion: print (tojson (result)); Problem gelöst. –

+0

@FerencStraub Das obige Code-Snippet funktioniert gut stripping Nullwertfelder im Ergebnis –

3

Beginnen Sie mit dem Abrufen einer eindeutigen Liste aller Schlüssel in der Sammlung, verwenden Sie diese Schlüssel als Abfragebasis und führen Sie eine Bulk-API-Operation mit einer geordneten Bulk-Aktualisierung durch. Die Aktualisierungsanweisung verwendet den Operator $unset, um die Felder zu entfernen.

Der Mechanismus zum Abrufen einer eindeutigen Schlüsselliste, die zum Zusammenstellen der Abfrage benötigt wird, ist über Map-Reduce möglich. Die folgende mapreduce Operation wird bevölkern eine getrennte Sammlung mit allen Tasten wie die _id Werte:

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" 
}) 

Um eine Liste aller dynamischen Schlüssel, laufen verschiedene auf der resultierende Sammlung:

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

Jetzt In der obigen Liste können Sie Ihre Abfrage zusammenstellen, indem Sie ein Objekt erstellen, dessen Eigenschaften in einer Schleife festgelegt werden. Normalerweise wird Ihre Anfrage diese Struktur hat:

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":""}]} 

können Sie dann die Verwendung Bulk API (erhältlich mit MongoDB 2.6 und höher) als eine Möglichkeit, das Updates für eine bessere Leistung bei der Abfrage über die Straffung. Insgesamt sollten Sie in der Lage sein, etwas zu haben, arbeiten als:

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

Dank für die Beantwortung. –

+0

@FerencStraub Keine Sorgen, gerne helfen :) – chridam

0

Wenn Sie einen einzelnen aktualisieren leere Parameter oder Sie bevorzugen Parameter für Parameter zu tun, können Sie die mongo updateMany Funktionalität verwenden:

db.comments.updateMany({year: ""}, { $unset : { year : 1 }}) 
Verwandte Themen