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

MongoDB drop duplicates with ensureIndex but keep the last entry not the first

我有一个重复的问题。

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

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

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

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

最简单的方法是什么?

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 的任何其他文档,我们可以将其删除。

您最终将对 collection 进行一次完整扫描,并对每个重复的元素进行 N 额外的数据库调用。

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

P.S.

Beware of bugs in the above code; I have only proved it correct, not tried it.

告诉我进展如何。

P.P.S.如果你还是不能对mongo中的所有collection进行排序,我会尝试这样做在应用层。基本上你找到你所有的 collections,用你想要的任何语言对它们进行排序,然后在那里也做同样的逻辑。