猫鼬合计不适用于$或

时间:2020-07-08 19:44:04

标签: javascript node.js mongodb mongoose

我正在使用聊天应用程序。我的架构如下:

{
  from: String,
  to: String,
  message: String,
  attachment: {
    name: String,
    size: Number,
    type: String,
  },
  unread: Boolean,
  sent: Date,
  seen: Date,
}

以下代码有效并返回最新消息:

查询1:

ChatDB.aggregate([
  { $match: {
    $or: [
      { from, to },
      { from: to, to: from },
    ],
  }},
  { $sort: { sent: -1 }},
  { $limit: messageBatchSize },
  { $sort: { sent: 1 }},
]);

但是,当我尝试通过在查询中包含时间戳进行分页时,它不再起作用:

查询2:

ChatDB.aggregate([
  { $match: {
    sent: { $lt: new Date(beforeTimestamp) },
    $or: [
      { from, to },
      { from: to, to: from },
    ],
  }},
  { $sort: { sent: -1 }},
  { $limit: messageBatchSize },
  { $sort: { sent: 1 }},
]);

如果我删除$or部分并仅对sent进行时间戳检查,那么一切正常,但是(当然)它将为所有用户返回结果,这不是我想要的:

查询3:

ChatDB.aggregate([
  { $match: {
    sent: { $lt: new Date(beforeTimestamp) },
  }},
  { $sort: { sent: -1 }},
  { $limit: messageBatchSize },
  { $sort: { sent: 1 }},
]);

起初,我认为它必须做一些事情,不要将id从字符串转换为ObjectId,而是将代码更改为相应地使用Types.ObjectId。但这甚至没有帮助。我的意思是,查询1 无需任何转换即可正常工作。

知道发生了什么吗?我的mongoose版本:

"mongoose": "^5.8.2",

编辑:

我尝试在mongo控制台中运行查询,它正确返回了结果:

> db.chats.aggregate([
...     {
...       $match: {
...         $or: [
...           { from: '5f0319f87278d056876952d5', to: 'org' },
...           { to: '5f0319f87278d056876952d5', from: 'org' },
...         ],
...         sent: { $lt: new Date('2020-07-08T17:05:34.288Z') }
...       }
...     },
...     { $sort: { sent: -1 }},
...     { $limit: 20 },
...     { $sort: { sent: 1 }}
...   ]);

1 个答案:

答案 0 :(得分:0)

我觉得把它放在第一位有点愚蠢。

原来的问题是fromto中的值属于Types.ObjectId类型,因为它们是从另一个集合中检索的。

ChatDB中存储的值是字符串。因此,从mongo控制台进行的查询工作正常(因为我正确提供了字符串),并且在代码中包含猫鼬的查询无法正常工作。

但是,我仍然不知道为什么查询1 有效。