MongoDB使用ensureIndex删除重复项,但保留最后一个条目不是第​​一个

时间:2015-02-18 11:17:35

标签: mongodb duplicates

我有一个重复的问题。

我试图删除MongoDB集合中的所有重复项,问题是我不想保留第一个条目,而是保留最后一个条目。

这是我保留第一个条目的方式:

db.CUDB.ensureIndex( { CUid: 1 }, { unique: true, dropDups: true } )

但我希望能够以相反的方式insureIndex并保留最后添加的条目而不是第一个。

最简单的方法是什么?

1 个答案:

答案 0 :(得分:2)

ensureIndex没有提供这样做的方法。此外,它不会告诉哪些值会被删除。

在你的情况下,我会尝试执行以下操作(肯定会慢一点,然后确保索引)。 我还假设你有一些字段(在我的情况下是created_at),这取决于你决定一个文档是否比另一个文档更老了:

var checked = {}; // basically a hash, which ensures O(1) lookup
db.coll.find().sort({created_at: -1}).forEach(function(o){
  if (o['CUid'] in checked){
    db.coll.remove({_id: o['_id']});
  } else {
    checked[o['CUid']] = 1;
  }
})

所以基本上我们以相反的顺序迭代你的所有文档(最新的文档)并检查我们是否已经看到你的CUid字段。如果我们没有,请将此文档保留原样并将其标记为已显示。如果稍后我们看到任何其他文档具有相同的CUid,我们可以将其删除。

对于每个重复的元素,最终会对您的集合进行一次完整扫描并进行N个额外的db调用。

反向排序将确保保存最新的元素。

P.S。

  

谨防上述代码中的错误;我只证明它是正确的,不是   试了一下。

告诉我它是怎么回事。

P.P.S。如果您仍然无法对mongo中的所有集合进行排序,我会尝试在应用层上执行此操作。基本上你找到你所有的收藏品,用你想要的任何语言对它们进行排序,然后在那里做同样的逻辑。