MongoDB:从 Projection 中删除重复记录

Posted

技术标签:

【中文标题】MongoDB:从 Projection 中删除重复记录【英文标题】:MongoDB: Remove duplicate records from 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)]

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

【问题讨论】:

【参考方案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 您不了解您实际上没有选择查询中的项目的哪一部分?这也在答案中。

以上是关于MongoDB:从 Projection 中删除重复记录的主要内容,如果未能解决你的问题,请参考以下文章

求助啊,tp下,mongodb如何查询后只返回某个字段值

MongoDB返回指定字段的方法

mongoDB projection 指定字段返回

MongoDB查询操作限制返回字段的方法

mongodb-查询

Clickhouse —— PROJECTION 创建物化删除