我有一个数组,并且它包含重复的ID ID,有没有办法删除其中一个重复的数组项?
userName: "abc",
_id: 10239201141,
rounds:
[{
"roundId": "foo",
"money": "123
},// Keep one of these
{// Keep one of these
"roundId": "foo",
"money": "123
},
{
"roundId": "foo",
"money": "321 // Not a duplicate.
}]
我想删除前两个中的一个,并保留第三个,因为ID和钱不会在数组中重复。
提前谢谢!
编辑我发现:
db.users.ensureIndex({'rounds.roundId':1,'rounds.money':1},{unique:true,dropDups:true})
这对我没有帮助。有人能帮我吗?我花了好几个小时试图解决这个问题。
问题是,我在两台机器上运行了我的node.js网站,因此两次推送相同的数据。知道这一点,重复数据应该是1索引。我做了一个简单的for循环,可以检测我的情况下是否有重复的数据,我怎么能用mongodb实现这个,所以它删除数组索引的数组对象?
for (var i in data){
var tempRounds = data[i]['rounds'];
for (var ii in data[i]['rounds']){
var currentArrayItem = data[i]['rounds'][ii - 1];
if (tempRounds[ii - 1]) {
if (currentArrayItem.roundId == tempRounds[ii - 1].roundId && currentArrayItem.money == tempRounds[ii - 1].money) {
console.log("Found a match");
}
}
}
}
答案 0 :(得分:1)
使用聚合框架计算每个文档的重复数据删除版本:
db.test.aggregate([
{ "$unwind" : "$stats" },
{ "$group" : { "_id" : "$_id", "stats" : { "$addToSet" : "$stats" } } }, // use $first to add in other document fields here
{ "$out" : "some_other_collection_name" }
])
使用$out
将结果放入另一个集合中,因为聚合无法更新文档。您可以将db.collection.renameCollection
与dropTarget
一起使用,将旧版集合替换为新的重复数据删除版本。但是,在废弃旧数据之前,请确保您做的正确。
警告:
1:这不保留stats
数组中元素的顺序。如果您需要保留订单,您将从数据库中检索每个文档,手动对数组客户端进行重复数据删除,然后更新数据库中的文档。
2:以下两个对象不会被视为彼此重复:
{ "id" : "foo", "price" : 123 }
{ "price" : 123, "id" : foo" }
如果您认为自己有混合关键订单,请使用$project
强制执行$unwind
阶段与$group
阶段之间的关键顺序:
{ "$project" : { "stats" : { "id_" : "$stats.id", "price_" : "$stats.price" } } }
请务必更改管道其余部分中的id -> id_
和price -> price_
,并将其重命名为最后的id
和price
,或者将其重命名为另一个$project
交换后{1}}。我发现,如果你没有为项目中的字段指定不同的名称,它就不会对它们重新排序,即使密钥顺序在MongoDB中的对象中有意义:
> db.test.drop()
> db.test.insert({ "a" : { "x" : 1, "y" : 2 } })
> db.test.aggregate([
{ "$project" : { "_id" : 0, "a" : { "y" : "$a.y", "x" : "$a.x" } } }
])
{ "a" : { "x" : 1, "y" : 2 } }
> db.test.aggregate([
{ "$project" : { "_id" : 0, "a" : { "y_" : "$a.y", "x_" : "$a.x" } } }
])
{ "a" : { "y_" : 2, "x_" : 1 } }
由于密钥顺序是有意义的,我认为这是一个错误,但它很容易解决。