首页 > 解决方案 > Mongo DB 聚合查找匹配

问题描述

我有两个集合,一个带有 user_message 的集合和一个带有消息的集合。在消息中,文档如下所示:

 "_id": ObjectId("...")
"message":{
start_date:date
end_date:date
active:bool,
id:int}

user_message集合中看起来像这样:

 "_id": ObjectId("...")
"message_id":string

我想要做的是集合中的一个聚合user_message,我在管道中添加一个 $lookup 阶段,我进入消息集合并在message.id相等的地方获取消息,message_id我想在active为真时获取消息,现在时间更大start_date然后更少end_date

我的尝试:

 let user_id = req.query.user_id;
    let dateTime = new Date();
    dateTime = moment(dateTime).format('YYYY-MM-DD HH:mm:ss');
    let messages =
      await db
      .collection('user_message')
      .aggregate([
        {
          $match: {
            user_id: user_id
          }
        },
        {
          $lookup:{
            from:"messages",
            localField:"message.id",
            foreignField:"message_id",
            as:"messages"
          }
        },
        {
           $match:{
            'messages.message.active': '1',
            'messages.message.end_date': {
              $gte: dateTime
            },
          'message.start_date': {
            $lte: dateTime
          }
           }
        },
        {
          $project:{
          messages: 1,
          }
        }
    ])
    .toArray();

我希望结果是这样的:

      message:{start_at:date,
               end_date:date,
                active:boo},
    _id: ObjectId("...")
   ]

标签: node.jsmongodb

解决方案


我认为这应该对你有用。我不确定消息文档中有多少消息,或者是否有多个 user_message 与消息文档匹配。但这是我想出的。管道在消息集合上执行:

[
{$match: {
  "message.active": true,
  "message.start_date": {
    $gte: ISODate('2020-01-01T05:00:00.000+00:00')
  },
  "message.end_date": {
    $lte: ISODate('2020-01-05T05:00:00.000+00:00')
  }
}}, 
{$lookup: {
  from: 'user_messages',
  localField: 'message.id',
  foreignField: 'message_id',
  as: 'user_message'
}}]

这会产生如下所示的文档:

_id:5e72155678117090fea3e141
message:Object
  start_date:2020-01-01T05:00:00.000+00:00
  end_date:2020-01-02T05:00:00.000+00:00
  active:true
  id:"message1"
user_message:Array
  0:Object
    _id:5e7214e71c9d44000080c1c9
    message_id:"message1"
    another_field:"hello"

您可以添加一个 $project 阶段以将结果清理为您想要的格式。


推荐阅读