首页 > 解决方案 > 来自所有用户的最新消息和一个返回空数组的单个用户的聚合查询

问题描述

我正在尝试获取用户 A 和任何其他用户之间的所有消息。

我的架构是:

const MostRecentMessageSchema = new Schema({
  to: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "user"
  },
  from: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "user"
  },
  conversation: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "conversation"
  },
  date: {
    type: Date,
    default: Date.now
  }
});

我的查询:

    await MostRecentMessages.aggregate(
      [
        {
          $match: {
            $or: [
              {
                to: id
              },
              {
                from: id
              }
            ]
          }
        },
        { $sort: { date: -1 } },
        {
          $group: {
            _id: "$from",
            from: {
              $first: "$from"
            },
            to: {
              $first: "$to"
            },
            conversation: {
              $first: "$conversation"
            },
            date: {
              $first: "$date"
            }
          }
        },
        {
          $lookup: {
            from: "conversations",
            localField: "conversation",
            foreignField: "_id",
            as: "conversation"
          }
        },
        { $unwind: { path: "$conversation" } },
        {
          $project: {
            from: {
              $cond: { if: { $eq: ["$to", id] }, then: "$from", else: "$to" }
            },
            to: {
              $cond: { if: { $eq: ["$to", id] }, then: "$to", else: "$from" }
            },
            conversation: "$conversation"
          }
        }
      ],
      function(err, docs) {
        if (err) console.log(err);
        else console.log("docs", docs);

        return res.json(docs);
      }
    );

但是,这会一直返回一个空数组。我在这里做错了什么?我还需要填充该conversation字段,这就是我这样做的原因$lookup,但其他事情根本上是错误的,因为它没有找到任何文档。

标签: javascriptmongodbmongoose

解决方案


弄清楚了。对于任何来到这里遇到同样问题的人,请参阅答案。id字符串必须转换为ObjectID


我是如何解决的:

    await MostRecentMessages.aggregate(
      [
        {
          $match: {
            $or: [
              { from: mongoose.Types.ObjectId(id) },
              { to: mongoose.Types.ObjectId(id) }
            ]
          }
        },
        { $project: { _id: 1, from: 1, to: 1, conversation: 1, date: 1 } },
        { $sort: { date: -1 } },
        {
          $group: {
            _id: "$sender",
            from: { $first: "$from" },
            to: { $first: "$to" },
            date: { $first: "$date" },
            conversation: { $first: "$conversation" }
          }
        }
      ],
      function(err, docs) {
        if (err) console.log(err);
        else console.log("docs", docs);

        return res.json(docs);
      }
    );

推荐阅读