Mongodb 如何在数组上使用$elemMatch,并将上层字段指定为查询的一部分

Mongodb 如何在数组上使用$elemMatch,并将上层字段指定为查询的一部分,mongodb,mongoose,mongodb-query,Mongodb,Mongoose,Mongodb Query,我想为一个特定的用户检索他与未读消息的聊天记录 假设我有这样一个简化的聊天模型: { lastMessageAt: Date, participants: [ { user: String(id), lastReadAt: Date } ] } 如何实现我的查询 我尝试过使用$elemMatch之类的方法,但lastMessageAt在这个级别上是未知的 ChatDB.find({ 'participants': { $elemM

我想为一个特定的用户检索他与未读消息的聊天记录

假设我有这样一个简化的聊天模型:

{
  lastMessageAt: Date,
  participants: [
    {
      user: String(id),
      lastReadAt: Date
    }
  ]
}
如何实现我的查询

我尝试过使用$elemMatch之类的方法,但lastMessageAt在这个级别上是未知的

ChatDB.find({
  'participants': {
    $elemMatch: { user: '12345', lastReadAt: { $lt: '$lastMessageAt' } }
  }
}

提前感谢您的帮助!:)

$elemMatch
操作员将在
ChatDB
集合中找到那些在
参与者中至少有一个元素符合您的条件的文档。此外,我的研究结束时的结论是,尚无法访问
$elemMatch
操作符中的其他文档字段。无论如何,如果这是您的目标,那么您可以使用以下查询:

ChatDB.aggregate([
  {
    $match: {
      "participants.user": "12345",
      $expr: {
        $lt: [
          "$participants.lastReadAt",
          "$lastMessageAt"
        ]
      }
    }
  }
])

如果您还想筛选真正符合条件的
参与者
,则需要添加投影阶段:


我发现解决方案是将聚合器与$unwind操作符一起使用

await ChatDB.aggregate([
      {
        $unwind: '$participants'
      },
      {
        $match: {
          'participants.user': '12345',
          $expr: {
            $lt: [
              '$participants.lastReadAt',
              '$lastMessageAt'
            ]
          }
        }
      }]);

希望这将是有用的

谢谢你的回答,不管怎样,你提到的查询不起作用,他们检索的聊天参与者中有user=12345,并且至少有一个参与者有未读消息。我想要的是检索那些user=12345且有未读消息的聊天记录。
await ChatDB.aggregate([
      {
        $unwind: '$participants'
      },
      {
        $match: {
          'participants.user': '12345',
          $expr: {
            $lt: [
              '$participants.lastReadAt',
              '$lastMessageAt'
            ]
          }
        }
      }]);