假设我有一个包含一组文档的集合。像这样的。
{ "_id" : ObjectId("4f127fa55e7242718200002d"), "id":1, "name" : "foo"}
{ "_id" : ObjectId("4f127fa55e7242718200002d"), "id":2, "name" : "bar"}
{ "_id" : ObjectId("4f127fa55e7242718200002d"), "id":3, "name" : "baz"}
{ "_id" : ObjectId("4f127fa55e7242718200002d"), "id":4, "name" : "foo"}
{ "_id" : ObjectId("4f127fa55e7242718200002d"), "id":5, "name" : "bar"}
{ "_id" : ObjectId("4f127fa55e7242718200002d"), "id":6, "name" : "bar"}
我想通过“名称”字段查找此集合中所有重复的条目。例如。 "foo"出现两次,"bar"出现 3 次。
最佳答案
接受的答案在大型集合上非常慢,并且不返回重复记录的 _id
。
聚合速度更快,可以返回 _id
s:
db.collection.aggregate([
{ $group: {
_id: { name: "$name" }, // replace `name` here twice
uniqueIds: { $addToSet: "$_id" },
count: { $sum: 1 }
} },
{ $match: {
count: { $gte: 2 }
} },
{ $sort : { count : -1} },
{ $limit : 10 }
]);
在聚合管道的第一阶段,$group
运算符按 name
字段聚合文档,并将分组记录的每个 _id
值存储在 uniqueIds
中。
$sum运算符将传递给它的字段的值相加,在本例中为常量 1
- 从而将分组记录的数量计算到 count
字段中。
在流水线的第二阶段,我们使用 $match
过滤 count
至少为 2 的文档,即重复。
然后,我们首先对最常见的重复项进行排序,并将结果限制在前 10 位。
此查询将输出最多 $limit
个具有重复名称的记录,以及它们的 _id
。例如:
{
"_id" : {
"name" : "Toothpick"
},
"uniqueIds" : [
"xzuzJd2qatfJCSvkN",
"9bpewBsKbrGBQexv4",
"fi3Gscg9M64BQdArv",
],
"count" : 3
},
{
"_id" : {
"name" : "Broom"
},
"uniqueIds" : [
"3vwny3YEj2qBsmmhA",
"gJeWGcuX6Wk69oFYD"
],
"count" : 2
}
https://stackoverflow.com/questions/9491920/