如何使用 MongoDB 聚合获取每个组的第一个,包括空值?

Mar*_*coS 7 mongodb aggregation-framework

在我的 MongoDBpeople集合中,我需要过滤具有相同“别名”属性值的人员,保留其中第一个,并保留所有具有空“别名”的人员。

一些样本人员数据:

{ "_id" : "1", "flag" : true,  "name" : "Alice",    "alias" : null },
{ "_id" : "2", "flag" : true,  "name" : "Bob",      "alias" : "afa776bea788cf4c" },
{ "_id" : "3", "flag" : true,  "name" : "Bobby",    "alias" : "afa776bea788cf4c" },
{ "_id" : "4", "flag" : true,  "name" : "Cristina", "alias" : null },
{ "_id" : "5", "flag" : false, "name" : "Diego",    "alias" : null },
{ "_id" : "6", "flag" : true,  "name" : "Zoe",      "alias" : "2211293acc82329a" },
Run Code Online (Sandbox Code Playgroud)

这是我期望的结果:

{ "_id" : "1", "name" : "Alice",    "alias" : null },
{ "_id" : "2", "name" : "Bob",      "alias" : "afa776bea788cf4c" },
{ "_id" : "4", "name" : "Cristina", "alias" : null },
{ "_id" : "6", "name" : "Zoe",      "alias" : "2211293acc82329a" },
Run Code Online (Sandbox Code Playgroud)

我提出了这个初始查询:

db.people.aggregate({ $group: { _id: '$alias', alias: { $first: '$alias' } } })
Run Code Online (Sandbox Code Playgroud)

我面临的第一个问题是,这仅返回_idalias字段,但我需要所有这些......

更新:我更改了一些示例数据以更好地反映我的用例,因为@user3100115答案解决了旧示例数据的问题,但没有解决真实数据的问题。

我所做的改变:

  • 添加一个具有空别名的文档(“Cristina”)(我的文档都有“别名”字段),因为我需要返回具有空别名值的所有文档,而不仅仅是第一个文档。

  • 添加一个布尔属性(“标志”),我也需要能够匹配它...即:使用find()Id do: db-people.find({flag:true}),但我不明白如何使用aggregate()...过滤更多字段

请告诉我您是否认为我应该更好地提出一个新问题......

sty*_*ane 6

您可以使用$first返回阶段_id中的值$group

db.people.aggregate([ 
    { '$match': { 'flag': true } }, 
    { '$project': {
        'name': 1,          
        'alias': { 
            '$cond': [
                { '$eq': [ '$alias', null ] }, 
                '$_id', 
                '$alias' 
            ]
        }
    }},
    { '$group': {
        '_id': '$alias',         
        'name':  { '$first': '$name' },          
        'id': { '$first': '$_id' }       
    }}, 
    { '$project': {
        'alias': {
            '$cond': [ 
                { '$eq': [ '$id', '$_id' ] }, 
                null, 
               '$_id' 
            ]
        }, 
        'name': 1,
        '_id': '$id'
    }}
])
Run Code Online (Sandbox Code Playgroud)

返回:

{ "_id" : "6", "name" : "Zoe", "alias" : "2211293acc82329a" }
{ "_id" : "4", "name" : "Cristina", "alias" : null }
{ "_id" : "2", "name" : "Bob", "alias" : "afa776bea788cf4c" }
{ "_id" : "1", "name" : "Alice", "alias" : null }
Run Code Online (Sandbox Code Playgroud)