Mongodb 使用聚合框架传递值

Mongodb 使用聚合框架传递值,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我在Mongo中有以下文档架构: { "_id": "an id", "title": "my title", "muted": "true", "participants": [{ "userid":12345, "more": "data" }, ... ], "messages": [{ "message", "details " } ... { } ] } 我正在尝试获取以下形式的对象数组: [ { "_id": "a

我在Mongo中有以下文档架构:

{ 
    "_id": "an id",
    "title": "my title",
    "muted": "true",
    "participants": [{ "userid":12345, "more": "data" }, ... ],
    "messages": [{ "message", "details " } ... { } ]
}
我正在尝试获取以下形式的对象数组:

[
    { 
        "_id": "an id", 
        "meta" 
        { 
            "title": "my title",
            "muted": "true",
            "participants": [12345, /* user ids only */ ],
        },
        "messages": [{ "message", "details " } ... { } ]
    }
]
我已经让聚合工作来生成消息和_id:

[
    { $match:
            {
                'participants.user_id': userId
            }
    },
    { $unwind: "$messages" },
    { $match: { 'messages.sent_at': { '$gte': new Date(date) }}},
    { $group: { _id: "$_id", messages: { $addToSet: "$messages" }}}
]

获取元数据需要什么魔力?

如果您只想在输出“参与者”中匹配
'participants.userid:12345

如果您希望
参与者中的所有用户id
,无论它是什么

db.collection.aggregate(
[
    { $match:
            {
                'participants.userid': 12345
            }
    },
    { $project : { "messages" : 1 ,"muted" : 1 , "title" : 1 , "messages" : 1 , "participants" : 1, "ids" : "$participants.userid"  } },
    { $unwind : "$participants"},    
    { $match:
            {
                'participants.userid': 12345
            }
    },
    { $unwind: "$messages" },    
    { $group: { _id: "$_id" , 
         muted : { $first : '$muted'}, title : { $first : '$title'}, 
         ids : { $first : '$ids'},
         messages: { $addToSet: "$messages" },
         participants: { $addToSet: "$participants.userid" }}},
    { $project : { "messages" : "$messages" ,'meta.muted': '$muted', 'meta.title': '$title', 'meta.participants': '$ids'} },
]
).result
输出:

{
    "0" : {
        "_id" : "an id",
        "messages" : [ 
            {
                "message2" : "details2 "
            }, 
            {
                "message" : "details "
            }
        ],
        "meta" : {
            "muted" : "true",
            "title" : "my title",
            "participants" : [ 
                 12345
            ]
        }
    }
}

在最后一个
$group
语句中,您需要告诉Mongo它应该返回哪些字段。目前,您需要的只是
\u id
消息
字段。假设聚合返回如下三个文档:

{ 
  "_id": 1111,
  "title": "my title",
  "muted": "true",
  "participants": [{ "userid":12345, "more": "data" }, ... ],
  "messages": { "message": "Foo" }
},
{ 
  "_id": 1111,
  "title": "my title",
  "muted": "true",
  "participants": [{ "userid":12345, "more": "data" }, ... ],
  "messages": { "message": "Bar" }
},
{ 
  "_id": 1111,
  "title": "my title",
  "muted": "true",
  "participants": [{ "userid":12345, "more": "data" }, ... ],
  "messages": { "message": "Baz" }
}
您已经在向Mongo请求一个包含
$push
操作符的所有消息的列表,所以我们已经解决了这个问题。对于其他字段,您不能执行以下操作:

毕竟,Mongo如何知道如何处理这三个
“我的标题”
值?还是将
的三个布尔值设为静音
?做一个数组?丢弃数据?连接它们

在这种情况下,由于所有三个值都是相同的(根据定义),您可以说“我不在乎,只给我其中任何一个”、“给我第二个结果”、“给我第一个”或“给我最后一个”。前两个是不可能的,因此我们只剩下
$first
$last

{$group: {
  _id: "$_id", 
  title: {$first: "$title"},
  muted: {$first: "$muted"}
}}

当然,在这种情况下使用哪一个并不重要。

在我的解决方案中,我将“参与者.用户id”更改为“参与者.用户id”,并删除$match,因为示例文档没有发送文件。我用关于参与者的两种可能性更新了答案。唯一的问题是参与者是一个数组的数组。我该如何解决这个问题?我更新了答案,添加了{$unwind:“$participants”},
{$group: {
  _id: "$_id", 
  title: 1,
  muted: "$muted"
}}
{$group: {
  _id: "$_id", 
  title: {$first: "$title"},
  muted: {$first: "$muted"}
}}