【问题标题】:MongoDB: Remove duplicate records from ProjectionMongoDB:从 Projection 中删除重复记录
【发布时间】:2014-04-11 12:30:28
【问题描述】:

如何从 mongoDB 投影中删除重复记录? 假设我有以下形式的我的 mongo 文档 -

{"_id":"55555454", "From":"Bob", "To":"Alice", "subject":"Hi", "date":"04102011"} 
{"_id":"55555455", "From":"Bob", "To":"Dave", "subject":"Hello", "date":"04102014"}
{"_id":"55555456", "From":"Bob", "To":"Alice", "subject":"Bye", "date":"04112013"}

当我做一个简单的投影时 db.col.find({}, {"From":1, "To":1, "_id"=0})

这显然会给我所有三个这样的记录。

{“发件人”:“鲍勃”,“收件人”:“爱丽丝”} {“发件人”:“鲍勃”,“收件人”:“戴夫”} {“发件人”:“鲍勃”, “致”:“爱丽丝”}

但是我想要的只是两条记录,这样 -

{"From":"Bob", "To":"Alice"} {"From":"Bob","To":"Dave"}

由于我的应用程序目前在 python 中(使用 pymongo),我正在做的是我正在使用

从记录列表中删除应用程序中的重复项
result = [dict(tupleized) for tupleized in set(tuple(item.items()) for item in l)]

是否有任何数据库方法可以应用于投影并且只给我两条记录。

【问题讨论】:

    标签: python sql mongodb pymongo projection


    【解决方案1】:

    您无法仅使用 find 与 MongoDB 和投影来减少和消除重复文档。

    find 命令将不起作用,因为您需要记住它正在向客户端返回一个游标,因此不能将结果减少到只有那些没有辅助传递的唯一文档。

    使用这个作为测试数据(删除_id):

    > db.test.find()
    { "From" : "Bob", "To" : "Alice", "subject" : "Hi", "date" : "04102011" }
    { "From" : "Bob", "To" : "Dave", "subject" : "Hello", "date" : "04102014" }
    { "From" : "Bob", "To" : "Alice", "subject" : "Bye", "date" : "04112013" }
    { "From" : "Bob", "To" : "Alice", "subject" : "Hi", "date" : "04102011" }
    { "From" : "Bob", "To" : "Dave", "subject" : "Hello", "date" : "04102014" }
    { "From" : "Bob", "To" : "Alice", "subject" : "Bye", "date" : "04112013" }
    { "From" : "Bob", "To" : "Dave", "subject" : "Hello", "date" : "04102014" }
    { "From" : "Bob", "To" : "Alice", "subject" : "Bye", "date" : "04112013" }
    { "From" : "George", "To" : "Carl", "subject" : "Bye", "date" : "04112013" }
    { "From" : "David", "To" : "Carl", "subject" : "Bye", "date" : "04112013" }
    

    你可以使用聚合:

    > db.test.aggregate({ $group: { _id: { "From": "$From", "To": "$To" }}})
    

    结果:

    {
        "result" : [
            {
                "_id" : {
                        "From" : "David",
                        "To" : "Carl"
                }
            },
            {
                "_id" : {
                        "From" : "George",
                        "To" : "Carl"
                }
            },
            {
                "_id" : {
                        "From" : "Bob",
                        "To" : "Dave"
                }
            },
            {
                "_id" : {
                        "From" : "Bob",
                        "To" : "Alice"
                }
            }
    ],
        "ok" : 1
    }
    

    Python 代码应该与上面建议的聚合管道非常相似。

    【讨论】:

      【解决方案2】:

      投影仅定义您希望在结果中出现的字段。这很像以下语句:

      SELECT From, To
      

      相对于

      的基本形式
      SELECT *
      

      所以你真正想做的就是这样:

      db.collection.find(
          { "From": "Bob", "To": "Alice" },
          { "From": 1, "To": 1 }
      )
      

      这实际上选择了您想要的记录,并且与以下形式大致相同:

      SELECT From, To
      FROM collection
      WHERE
         From = "Bob"
         AND To = "Alice"
      

      如果实际上以某种方式产生“重复”结果,您可以使用聚合删除它:

      db.collection.aggregate([
         { "$match": {
             "From": "Bob", "To": "Alice"
         }}
         { "$group": {
             "_id": { 
                 "From": "$From", "To": "$To"
             }
         }}       
      ])
      

      【讨论】:

      • 感谢您抽出宝贵时间回答。我明白什么是投影,但我想要更多——从那个投影视图中删除重复的项目!
      • @sanj 您不了解您实际上没有选择查询中的项目的哪一部分?这也在答案中。
      猜你喜欢
      • 1970-01-01
      • 2021-07-12
      • 1970-01-01
      • 2012-08-23
      • 2016-01-07
      • 1970-01-01
      • 1970-01-01
      • 2019-11-25
      相关资源
      最近更新 更多