Mongoose按内部对象(ObjectID)中的字段查找

igetnqfo  于 2023-01-31  发布在  Go
关注(0)|答案(3)|浏览(189)

例如我有两个模型

const User = new Schema({
  name: { type: String },
});
const Message = new Schema({
  user: { type: ObjectId, ref: 'User' },
  message: { type: String },
});

如何通过用户中的"name"键查找消息?
不管用

exports.get = async (req, res) => {
  return Message.find({ "user.name": req.query.name })
    .populate('user', 'name')
    .then((data) => res.json(data));
}

我明白为什么"www.example.com"不起作用,但我不知道如何解决它user.name" doesn't work, but I don't know how to solve it

hl0ma9xz

hl0ma9xz1#

Mongodb中没有 join 的概念,因此我建议使用如下的直接模式定义:

const User = new Schema({
  name: { type: String },
});

const Message = new Schema({
  user: [User],
  message: { type: String },
});

那么你就不需要再用populate了,你会得到这样的代码:

Message.find({ "user.name": req.query.name })

但是,如果您仍然喜欢使用当前的方法,您可以尝试这个:

Message.find()
  .populate({
    path: "user",
    match: {
      name: req.query.name
    }
  })
...
91zkwejq

91zkwejq2#

您可能希望使用$lookup:

exports.get = async (req, res) => {
  return Message.aggregate([
    {
      $lookup: { // Aggregate operation
        from: 'users',
        pipeline: [
          {
            $match: {
              name: req.query.name, // If not match, it still returns null, that's why we need the skip operation below
            }
          }
        ],
        as: 'user'
      }
    }, {
      $match: { // Skip operation: 
        "user": { $ne: [] }
      }
    }
  ])
  .then((data) => res.json(data));
}
hgqdbh6s

hgqdbh6s3#

基本上,您需要表的正确排序,用户必须是主表,消息必须是从中查找的辅助表。查询如下所示;

exports.get = async (req, res) => {
    return User.aggregate([
        {
            $match: {
                name: req.query.name
            },
            $lookup: {
                from: 'Messages',
                localField: "_id",
                foreignField: "user",
                as: "Messages"
            }
        }
    ])
        .then((data) => res.json(data));
}

或者,如果你想要一个干净或更好的结果,那么你可以做以下:

exports.get = async (req, res) => {
    return User.aggregate([
        {
            $match: {
                name: req.query.name
            },
            $lookup: {
                let: { id: _id },
                from: 'Messages',
                pipeline: [
                    {
                        $match: {
                            $expr: { $eq: ["$user", "$$id"] }
                        }
                    },
                    {
                        $project: {
                            user: 0
                        }
                    }
                ],
                as: "Messages"
            }
        }
    ])
        .then((data) => res.json(data));
}

这将返回所有消息作为一个数组与字段名消息的“姓名”的人,例如;

{
   _id: 123,
   name: Ali,
   Messages: [{_id: 1234, message: "Hello"},{_id: 12345, message: "Hi"} ]
}

相关问题