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,用你想要的任何语言对它们进行排序,然后在那里也做同样的逻辑。
我有一个重复的问题。
我正在尝试从 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,用你想要的任何语言对它们进行排序,然后在那里也做同样的逻辑。