MongoDB查询查找数组中具有重复值的文档

时间:2017-10-05 12:59:50

标签: arrays mongodb mapreduce

tldr; 我正在努力构建一个

的查询
  1. 进行聚合以获取某个键上的值计数(“original_text_source”),
  2. 位于数组
  3. 中的子文档中

    完整说明

    我嵌入的文档包含如下结构的数组:

    {
        "_id" : ObjectId("0123456789"),
        "type" : "some_object",
        "relationships" : {
            "x" : [ ObjectId("0123456789") ],
            "y" : [ ObjectId("0123456789") ],
        },
        "properties" : [ 
            {
                "a" : "1"
            }, 
            {
                "b" : "1"
            }, 
            {
                "original_text_source" : "foo.txt"
            },
        ]
    }
    

    文档是从精确的10k文本文件创建的,在各种文件夹中排序。在将文档插入MongoDB(批量)期间,我搞砸了并移动了几个文件,导致一个文件被导入两次(我的数据库有1000个文档的计数),但显然我不知道它是哪一个。由于其中一个“original_text_source”值的计数必须为2,所以我打算只删除一个。

    我阅读了$elemMatch的解决方案,但由于我的数组元素是一个文档,我不知道如何继续。也许用mapReduce?但是我无法将逻辑转移到我的doc结构中。

    我也可以创建一个新的集合并重新上传所有内容,但是如果我再次陷入困境,我宁愿学习如何查询重复项。看起来更优雅: - )

3 个答案:

答案 0 :(得分:1)

运行以下命令:

db.collection.aggregate([
  { $group: {
    _id: { name: "$properties.original_text_source" },
    idsForDuplicatedDocs: { $addToSet: "$_id" },
    count: { $sum: 1 } 
  } }, 
  { $match: { 
    count: { $gte: 2 } 
  } },
  { $sort : { count : -1} }
]);

如果一个集合包含您在问题中显示的文档的两个副本,则上面的命令将返回:

{
    "_id" : {
        "name" : [ 
            "foo.txt"
        ]
    },
    "idsForDuplicatedDocs" : [ 
        ObjectId("59d631d2c26584cd8b7b3337"), 
        ObjectId("59d631cbc26584cd8b7b3333")
    ],
    "count" : 2
}

哪里......

  • 属性_id.name是重复的properties.original_text_source
  • 的值
  • 属性idsForDuplicatedDocs包含每个具有重复_id
  • 的文档的properties.original_text_source

答案 1 :(得分:1)

您可以使用以下简单聚合查找重复项:

db.collection.aggregate(
{ $group: { _id: "$properties.original_text_source", docIds: { $push: "$_id" }, docCount: { $sum: 1 } } },
{ $match: { "docCount": { $gt: 1 } } }
)

给你这样的东西:

{
"_id" : [ 
    "foo.txt"
],
"docIds" : [ 
    ObjectId("59d6323613940a78ba1d5ffa"), 
    ObjectId("59d6324213940a78ba1d5ffc")
],
"docCount" : 2.0
}

答案 2 :(得分:-1)

"reviewAndRating": [
    {
      "review": "aksjdhfkashdfkashfdkjashjdkfhasdkjfhsafkjhasdkjfhasdjkfhsdakfj",
      "productId": "5bd956f29fcaca161f6b7517",
      "_id": "5bd9745e2d66162a6dd1f0ef",
      "rating": "5"
    },
    {
      "review": "aksjdhfkashdfkashfdkjashjdkfhasdkjfhsafkjhasdkjfhasdjkfhsdakfj",
      "productId": "5bd956f29fcaca161f6b7518",
      "_id": "5bd974612d66162a6dd1f0f0",
      "rating": "5"
    },
    {
      "review": "aksjdhfkashdfkashfdkjashjdkfhasdkjfhsafkjhasdkjfhasdjkfhsdakfj",
      "productId": "5bd956f29fcaca161f6b7517",
      "_id": "5bd974622d66162a6dd1f0f1",
      "rating": "5"
    }
  ]