使用MongoDB聚合时出现错误“无法从BSON类型objectId转换为String”

时间:2019-11-11 17:44:52

标签: javascript node.js mongodb mongoose

我正在尝试获取用户1和用户N之间每次对话的最后一条消息。

我设法将以下内容一起编译,但是它抛出了上述错误。我该如何使用ObjectIds解决这个问题,因为这是数据库中的内容,而不是字符串?

    await MostRecentMessages.aggregate(
      [
        {
          $match: {
            $or: [
              { from: mongoose.Types.ObjectId(id) },
              { to: mongoose.Types.ObjectId(id) }
            ],
            deletedBy: { $ne: id }
          }
        },
        { $sort: { date: -1 } },
        { $project: { _id: 1, from: 1, to: 1, conversation: 1, date: 1 } },
        {
          $group: {
            _id: {
              lastMessage: {
                $cond: [
                  {
                    $gt: [
                      { $substr: ["$to", 0, 1] },
                      { $substr: ["$from", 0, 1] }
                    ]
                  },
                  { $concat: ["$to", " and ", "$from"] },
                  { $concat: ["$from", " and ", "$to"] }
                ]
              }
            },
            conversation: { $first: "$$ROOT" }
          }
        },
        {
          $lookup: {
            from: "conversations",
            localField: "conversation",
            foreignField: "_id",
            as: "conversation"
          }
        },
        { $unwind: { path: "$conversation" } },
        {
          $lookup: {
            from: "users",
            localField: "to",
            foreignField: "_id",
            as: "to"
          }
        },
        { $unwind: { path: "$to" } },
        {
          $lookup: {
            from: "users",
            localField: "from",
            foreignField: "_id",
            as: "from"
          }
        },
        { $unwind: { path: "$from" } }
      ],
      function(err, docs) {
        if (err) {
          console.log(err);
        } else {
          console.log("MostRecentMessages", docs);
          return res.json(docs);
        }
      }
    );

我的模式,如果有关系的话:

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"
  },
  deletedBy: {
    type: [String]
  },
  date: {
    type: Date,
    default: Date.now
  }
});

编辑

以下是5个相关文档:

// db.MostRecentMessages

_id:5dca7a61e95bd3341cad64b9
to:5dca58c21825d8269a32cb10
from:5dca58ce1825d8269a32cb11
conversation:5dca7aea51b626350fa865dd
date:2019-11-12T09:24:49.906+00:00

_id:5dca7ab0d3a44a34c98b7263
to:5dca58ce1825d8269a32cb11
from:5dca58c21825d8269a32cb10
conversation:5dca7ab0d3a44a34c98b7262
date:2019-11-12T09:26:08.125+00:00
// db.Conversation

_id:5dca7a61e95bd3341cad64b8
text:"Test1"
user:5dca58ce1825d8269a32cb11 // sender
recipient:5dca58c21825d8269a32cb10
createdAt:2019-11-12T09:24:49.827+00:00

_id:5dca7ab0d3a44a34c98b7262
text:"Test2"
user:5dca58c21825d8269a32cb10 // sender
recipient:5dca58ce1825d8269a32cb11
createdAt:2019-11-12T09:26:08.105+00:00

_id:5dca7aea51b626350fa865dd
text:"Test3"
user:5dca58ce1825d8269a32cb11 // sender
recipient:5dca58c21825d8269a32cb10
createdAt:2019-11-12T09:27:06.562+00:00

我复制并粘贴了以下答案,但它仅返回文本为Test2的消息

1 个答案:

答案 0 :(得分:1)

评论链接仅供您参考... 现在,让我们看看有什么用(对于您来说听起来可能像“ deja vu”,但它可以用!)。所有(以及您前面提到的错误)都发生在$ group阶段

db.lastMessage.aggregate([
  {
    $match: {
      $or: [
        {
          from: ObjectId("5a934e000102030405000001")
        },
        {
          to: ObjectId("5a934e000102030405000001")
        }
      ],
      deletedBy: {
        $ne: ObjectId("5a934e000102030405000001")
      }
    }
  },
  {
    $sort: {
      date: -1
    }
  },
  {
    $project: {
      _id: 1,
      from: 1,
      to: 1,
      conversation: 1,
      date: 1
    }
  },
  {
    $group: {
      _id: {
        userConcerned: {
          $cond: {
            if: {
              $eq: [
                "$to",
                ObjectId("5a934e000102030405000001")
              ]
            },
            then: "$to",
            else: "$from"
          }
        },
        interlocutor: {
          $cond: {
            if: {
              $eq: [
                "$to",
                ObjectId("5a934e000102030405000001")
              ]
            },
            then: "$from",
            else: "$to"
          }
        }
      },
      from: {
        $first: "$from"
      },
      to: {
        $first: "$to"
      },
      date: {
        $first: "$date"
      },
      conversation: {
        $first: "$conversation"
      }
    }
  },
  {
    $lookup: {
      from: "conversations",
      localField: "conversation",
      foreignField: "_id",
      as: "conversation"
    }
  },
  {
    $unwind: {
      path: "$conversation"
    }
  },
  {
    $lookup: {
      from: "users",
      localField: "to",
      foreignField: "_id",
      as: "to"
    }
  },
  {
    $unwind: {
      path: "$to"
    }
  },
  {
    $lookup: {
      from: "users",
      localField: "from",
      foreignField: "_id",
      as: "from"
    }
  },
  {
    $unwind: {
      path: "$from"
    }
  }
])

You can verify here。我刚刚用您在其他问题中已经提供的小组讨论修改了小组讨论。