删除重复的数组对象 mongodb
Remove duplicate array objects mongodb
我有一个数组,它在两个 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 和 money 在数组中不重复。
提前致谢!
我发现的编辑:
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");
}
}
}
}
使用聚合框架计算每个文档的去重版本:
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
。我发现,如果您不为项目中的字段指定不同的名称,它不会对它们重新排序,即使键顺序在 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 } }
由于键顺序有意义,我认为这是一个错误,但它很容易解决。
我有一个数组,它在两个 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 和 money 在数组中不重复。
提前致谢!
我发现的编辑:
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");
}
}
}
}
使用聚合框架计算每个文档的去重版本:
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
。我发现,如果您不为项目中的字段指定不同的名称,它不会对它们重新排序,即使键顺序在 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 } }
由于键顺序有意义,我认为这是一个错误,但它很容易解决。