Mongo数据库聚合查找匹配

时间:2020-03-18 12:18:34

标签: node.js mongodb

我有两个集合,一个带有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等于{{1 }},并且我想在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();

1 个答案:

答案 0 :(得分:0)

我认为这应该对您有用。我不确定消息文档中将包含多少条消息,或者不确定是否有多个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阶段来清理结果,使其具有所需的格式。