如何从mongodb集合中删除空字符串?

时间:2015-11-02 11:32:49

标签: mongodb

我有一个“mongodb colllenctions”,我想用它来删除“空字符串”。

由此:

{
    "_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", 
}

我怎么解决?

3 个答案:

答案 0 :(得分:3)

首先获取集合中所有密钥的不同列表,使用这些密钥作为查询基础,并使用批量API操作执行有序批量更新。更新语句使用 $unset 运算符删除字段。

通过 Map-Reduce 可以获得组合查询所需的不同键列表的机制。以下mapreduce操作将使用所有键作为_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"
})

要获取所有动态键的列表,请在生成的集合上运行distinct:

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 :(得分:3)

请尝试在Mongo shell中执行以下代码片段,该代码片段会删除包含空值或空值的字段

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

答案 2 :(得分:0)

如果您需要更新单个空白参数或者您更喜欢按参数执行参数,则可以使用mongo updateMany 功能:

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