【问题标题】:MongoDB query to find document with duplicate value in arrayMongoDB查询以查找数组中具有重复值的文档
【发布时间】:2017-10-05 12:59:50
【问题描述】:

tldr;我正在努力构建一个查询

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

完整说明

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

{
    "_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 期间(分批),我搞砸并移动了一些文件,导致一个文件被导入两次(我的数据库的计数正好为 10001 个文档),但显然我不知道它是哪一个.由于“original_text_source”值之一的计数必须为 2,因此我打算只删除一个。

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

我也可以只创建一个新集合并重新上传所有集合,但万一我又搞砸了,我宁愿学习如何查询重复项。看起来更优雅:-)

【问题讨论】:

    标签: arrays mongodb mapreduce


    【解决方案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】:

    运行以下命令:

    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 包含每个具有重复properties.original_text_source 的文档的_id

    【讨论】:

      【解决方案3】:
      "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"
          }
        ]
      

      【讨论】:

      • 嗨@SUmit 你能详细说明为什么它是一个解决方案吗?
      • 虽然这段代码 sn-p 可以解决问题,但including an explanation 确实有助于提高帖子的质量。请记住,您正在为将来的读者回答问题,而这些人可能不知道您的代码建议的原因。也请尽量不要用解释性的 cmets 挤满你的代码,这会降低代码和解释的可读性!
      • @GuillaumeRAYMOND 现在我没有问题了,感谢您回复我
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-02
      • 1970-01-01
      相关资源
      最近更新 更多