首先獲取集合中所有鍵的明確列表,使用這些鍵作爲查詢基礎並使用批量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();
}
})
它只從第一行刪除空的項目,但剩下的其他地方是空的項目。我仍然試圖找出問題所在。 shell寫道:[object Object],[object Object],[object Object] ... –
使用這個函數:print(tojson(result));問題解決了。 –
@FerencStraub上面的代碼片段工作得很好剝離結果中的空值字段 –