2015-11-02 114 views
5

我有一個「mongodb colllenctions」,我想刪除它的鍵「空字符串」。如何從mongodb集合中刪除空字符串?

從這:

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

我想獲得這樣的結果:

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

我怎麼能解決呢?

回答

2

請嘗試執行在蒙戈外殼下面的代碼片段如果需要更新單個這條與空或空值

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

它只從第一行刪除空的項目,但剩下的其他地方是空的項目。我仍然試圖找出問題所在。 shell寫道:[object Object],[object Object],[object Object] ... –

+0

使用這個函數:print(tojson(result));問題解決了。 –

+0

@FerencStraub上面的代碼片段工作得很好剝離結果中的空值字段 –

3

首先獲取集合中所有鍵的明確列表,使用這些鍵作爲查詢基礎並使用批量API操作進行有序批量更新。更新語句使用$unset運算符刪除字段。

通過Map-Reduce可以獲得您需要組裝查詢的不同密鑰列表的機制。下面精簡操作將填充單獨收集的所有鍵作爲_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" 
}) 

要獲得所有動態密鑰列表,在結果集合運行不同:

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

現在根據上面的列表,您可以通過創建一個將其屬性設置爲循環的對象來組裝您的查詢。通常情況下您的查詢都會有這樣的結構:

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

然後,您可以使用Bulk API(可與MongoDB的2.6及以上),作爲簡化與上面的查詢性能更好的更新的方式。總體而言,你應該能有一些工作爲:

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

謝謝回答。 –

+0

@FerencStraub不用擔心,樂意幫忙:) – chridam

0

領域或者你更喜歡通過參數來完成參數爲空參數,您可以使用蒙戈updateMany功能:

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