2015-11-02 109 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 }})