使用Mongoose在MongoDB中查询引用的文档

时间:2018-12-03 14:25:36

标签: mongodb mongodb-query aggregation-framework

这是集合BlogPosts中的文档:

{
    _id: ObjectId("..."),
    post_title: "Hello World!",
    post_body: "",
    comments: [
        { user_id: ObjectId("123"), body: "nice post!" },
        { user_id: ObjectId("456"), body: "awesome!" },
    ]
}

我想显示带有用户名字的注释,该注释可以在Users集合的引用文档中找到:

{
    _id: ObjectId("123"),
    first_name: "Marion",
    last_name: "Smith",
    email_address: "marion@example.com",
    password: "..."
}

在从此引用数据中包含BlogPosts的同时,有没有办法检索first_name文档?

例如,我正在寻找这样的输出(每个注释都有一个名字):

{
    _id: ObjectId("..."),
    post_title: "Hello World!",
    post_body: "",
    comments: [
        { user_id: ObjectId("..."), first_name: "Marion",  body: "nice post!" },
        { user_id: ObjectId("..."), first_name: "Margaret", body: "awesome!" },
    ]
}

我正在使用猫鼬。

2 个答案:

答案 0 :(得分:1)

您可以使用以下汇总

db.collection.aggregate([
  { "$unwind": "$comments" },
  { "$lookup": {
    "from": "users",
    "let": { "userId": "$comments.user_id" },
    "pipeline": [{ "$match": { "$expr": { "$eq": ["$$userId", "$_id"] } } }],
    "as": "user"
  }},
  { "$addFields": {
    "comments.first_name": { "$arrayElemAt": ["$user.first_name", 0] }
  }},
  { "$group": {
    "_id": "$_id",
    "comments": { "$push": "$comments" },
    "post_title": { "$first": "$post_title" },
    "post_body": { "$first": "$post_body" }
  }}
])

答案 1 :(得分:0)

此后,我发现了一种更简单的方法,仅使用Populate

BlogPosts
    .findOne({_id: req.params.id})
    .populate('comments.user_id', ['first_name', 'last_name'])
    .then(post => console.log(post))

在BlogPosts的架构中,应为ref字段定义comments.user_id

const User = require('./User.model.js');

const blogPostSchema = new Schema({
    post_title: { type: String },
    post_body: { type: String },
    comments: [{
        user_id: {
            type: Schema.ObjectId,
            ref: 'User'  <-------- here
        }
    }]
});

const BlogPost = mongoose.model('BlogPost', blogPostSchema);

module.exports = BlogPost;