MongoDB:有条件地删除重复项

时间:2014-08-06 14:39:56

标签: mongodb

我有这样的文件集:

{
    "word": "foo",
    "likes": 10,
    "dislikes": 1,
},
{
    "word": "foo",
    "likes": 5,
    "dislikes": 9,
},

麻烦的是,我的收藏中充斥着类似的文件(共享相同的词,但不同的数据)。我想删除这些类似的,几乎重复的条目。

现在,一种简单的方法是使用唯一索引:

db.entries.ensureIndex({'word' : 1}, {unique : true, dropDups : true})

但我觉得我可以做得更好。也许我可以使用喜欢/不喜欢的数据来计算比率并保留最佳条目,同时删除其余条目。

我想知道这是否可以使用MapReduce和Mongo CLI Javascript魔法,或者我应该使用MongoDB原语以编程方式解决这个问题?

编辑:此次清理是一次性事件,性能并不重要。

1 个答案:

答案 0 :(得分:3)

db.entries.aggregate(
            [
              {$group:{_id:'$word',
                       entries:{'$push':
                                   {score:{ $divide: [ "$$ROOT.likes", "$$ROOT.dislikes" ]},
                                    _id:"$$ROOT._id"}
                                   }
                               }
                       }
             ,{$unwind: '$entries'}, 
              {$sort: {'entries.score': -1}} ,
              {$group: {_id: '$_id', 'entries': {$push: '$$ROOT.entries'}}}
           ])

当不喜欢为0时处理案例。也许你可以使用$$ROOT.dislikes+1 我不知道如何在Javascript CLI中输出。我假设docs是输出。

var duplicate_ids = [];
docs.forEach(function(doc){
    for(var i=1;i<doc.entries.length;i++){
       duplicate_ids.push(doc.entres._id);
     }
});
db.entries.remove({_id:{'$in':duplicate_ids}})

这可以解决您的问题。