如何使用MongoDB聚合获取每个组的第一个,包括null? [英] How to use MongoDB aggregate to get the first of each group, including nulls?

查看:112
本文介绍了如何使用MongoDB聚合获取每个组的第一个,包括null?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的MongoDB people集合中,我需要过滤具有相同别名"属性值的人,保留他们的第一个,并且还为所有人保留一个空的别名".

In my MongoDB people collection I need to filter people with the same 'alias' property value, keeping the first one of them, and also keeping all people with a null 'alias'.

一些样本人员数据:

{ "_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" },

这是我期望的结果:

{ "_id" : "1", "name" : "Alice",    "alias" : null },
{ "_id" : "2", "name" : "Bob",      "alias" : "afa776bea788cf4c" },
{ "_id" : "4", "name" : "Cristina", "alias" : null },
{ "_id" : "6", "name" : "Zoe",      "alias" : "2211293acc82329a" },

我已经有了这个初始查询:

I've come with this initial query:

db.people.aggregate({ $group: { _id: '$alias', alias: { $first: '$alias' } } })

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

The first problem I face is that this returns only _id and alias fields, but I need all of them...

更新: 我已经更改了一些样本数据以更好地反映我的用例,因为@ user3100115答案解决了旧样本数据的问题,而不是真实数据的问题.

UPDATE: I have changed a bit sample data to better reflect my use case, since @user3100115 answer solves the issue for old sample data, but not for real data.

我所做的更改:

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

  • add one more document ("Cristina") with a null alias (my documents all have "alias" field), since I need all documents with a null alias value to be returned, and not just the first one.

再添加一个布尔值属性(标志"),我也需要将其匹配...即:使用find()我会这样做:db-people.find({flag:true}),但我不这样做了解如何使用aggregate() ...

add one more boolean property ("flag"), which I need to be able to match, too... I.e.: using find() I'd do: db-people.find({flag:true}), but I don't understand how to filter with more fields with aggregate()...

请告诉我您是否认为我最好提出一个新问题...

推荐答案

您可以使用 $first 返回_id值._S_group"rel =" nofollow> $group 阶段.

You can use $first to return the the _id value in the $group stage.

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'
    }}
])

哪个返回:

{ "_id" : "6", "name" : "Zoe", "alias" : "2211293acc82329a" }
{ "_id" : "4", "name" : "Cristina", "alias" : null }
{ "_id" : "2", "name" : "Bob", "alias" : "afa776bea788cf4c" }
{ "_id" : "1", "name" : "Alice", "alias" : null }

这篇关于如何使用MongoDB聚合获取每个组的第一个,包括null?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆