聚合查询上的Mongodb填充字段

聚合查询上的Mongodb填充字段,mongodb,mongoose,nosql,aggregation-framework,Mongodb,Mongoose,Nosql,Aggregation Framework,我有这三个系列(产品、用户和评论) 1。产品型号 var ProductSchema = new Schema({ title: { type: String, text: true, required: true }, description: { type: String, required: true }, category: [{ type: String, required: true }], type: [{ t

我有这三个系列(产品、用户和评论)

1。产品型号

var ProductSchema = new Schema({
  title:          { type: String, text: true, required: true },
  description:    { type: String, required: true },
  category:       [{ type: String, required: true }],
  type:           [{ type: String, required: true }],
  isUsed:         { type: Boolean, },
  manufacturer:   { type: String },
  price:          { type: Number },
});
var UserSchema = new Schema({
  firstName:      { type: String, text: true, required: true },
  lastName:       { type: String, text: true, required: true },
  country:        [{ type: String, required: true }],
  phoneNumber:    [{ type: String, required: true }]
});
var CommentSchema = new Schema({
  comment:        { type: String, text: true, required: true },
  commented_by:   { type: Schema.Types.ObjectId, ref: 'User', required: true },
  commented_on:   { type: Schema.Types.ObjectId, ref: 'Product', required: true }
});
2。用户模型

var ProductSchema = new Schema({
  title:          { type: String, text: true, required: true },
  description:    { type: String, required: true },
  category:       [{ type: String, required: true }],
  type:           [{ type: String, required: true }],
  isUsed:         { type: Boolean, },
  manufacturer:   { type: String },
  price:          { type: Number },
});
var UserSchema = new Schema({
  firstName:      { type: String, text: true, required: true },
  lastName:       { type: String, text: true, required: true },
  country:        [{ type: String, required: true }],
  phoneNumber:    [{ type: String, required: true }]
});
var CommentSchema = new Schema({
  comment:        { type: String, text: true, required: true },
  commented_by:   { type: Schema.Types.ObjectId, ref: 'User', required: true },
  commented_on:   { type: Schema.Types.ObjectId, ref: 'Product', required: true }
});
3。评论模式

var ProductSchema = new Schema({
  title:          { type: String, text: true, required: true },
  description:    { type: String, required: true },
  category:       [{ type: String, required: true }],
  type:           [{ type: String, required: true }],
  isUsed:         { type: Boolean, },
  manufacturer:   { type: String },
  price:          { type: Number },
});
var UserSchema = new Schema({
  firstName:      { type: String, text: true, required: true },
  lastName:       { type: String, text: true, required: true },
  country:        [{ type: String, required: true }],
  phoneNumber:    [{ type: String, required: true }]
});
var CommentSchema = new Schema({
  comment:        { type: String, text: true, required: true },
  commented_by:   { type: Schema.Types.ObjectId, ref: 'User', required: true },
  commented_on:   { type: Schema.Types.ObjectId, ref: 'Product', required: true }
});
然后,当发送请求以获取特定的产品时,这就是后台运行的mongoose代码

      var aggregate = Product.aggregate([

        { "$match": { _id: ObjectId(req.params.id) } },  /** which is the product id **/
        { "$limit": 1 },
   
        { 
          $lookup: {
              from: 'comments',
              let: { id: "$_id" },
              pipeline: [
                { $match: { $expr: { $eq: [ "$commented_on.product", "$$id" ] } } },
            ],
              as: "comments"
            }
        },  
       
        { 
          $addFields: {
            comments: "$comments",
            comments_no: { $size: "$comments" },
            hasCommented: { $in: [ObjectId(req.user._id), "$comments.commented_by" ] }, /** req.user._id  is the user's id **/
          }
        },
          {
            $project: {
              _id: 1,
              title: 1,
              description: 1,
              category: 1,
              type: 1,
              price: 1,
              comments: 1,
              hasCommented: 1,
              comments_no: 1,
            }
          }
      ]);

输出

{
    "_id": "5f992b5338f5f035f35911c5",
    "title": "Some title here..."
    "description": Some description here ...
    "price": 1000,
    "category": "Clothing",
    "type": "shoe",
    "comments": [ 
        {
          "comment": "Nice Product",
          "commented_by": "5f992b5338f5f035f35911b2",
          "commented_on": "5f992b5338f5f035f35911c5"
        },
        {
          "comment": "I like this product",
          "commented_by": "5f992b5338f5f035f35911a2",
          "commented_on": "5f992b5338f5f035f35911c5"
        },
        {
          "comment": "Great, I like it!",
          "commented_by": "5f992b5338f5f035f35911c8",
          "commented_on": "5f992b5338f5f035f35911c5"
        } 
                 
    ],
    "hasCommented": true,
    "comments_no": 3
}
{
    "_id": "5f992b5338f5f035f35911c5",
    "title": "Some title here..."
    "description": Some description here ...
    "price": 1000,
    "category": "Clothing",
    "type": "shoe",
    "comments": [ 
        {
          "comment": "Nice Product",
          "commented_by": { 
              "_id": "5f992b5338f5f035f35911b2",
              "firstName": "Jack",
              "lastName": "Sparrow" 
          },
          "commented_on": "5f992b5338f5f035f35911c5"
        },
        {
          "comment": "I like this product",
          "commented_by": { 
              "_id": "5f992b5338f5f035f35911a2",
              "firstName": "John",
              "lastName": "Doe" 
          },
          "commented_on": "5f992b5338f5f035f35911c5"
        },
        {
          "comment": "Great, I like it!",
          "commented_by": { 
              "_id": "5f992b5338f5f035f35911c8",
              "firstName": "Mary",
              "lastName": "Jane" 
          },
          "commented_on": "5f992b5338f5f035f35911c5"
        } 
                 
    ],
    "hasCommented": true,
    "comments_no": 3
}
预期结果

{
    "_id": "5f992b5338f5f035f35911c5",
    "title": "Some title here..."
    "description": Some description here ...
    "price": 1000,
    "category": "Clothing",
    "type": "shoe",
    "comments": [ 
        {
          "comment": "Nice Product",
          "commented_by": "5f992b5338f5f035f35911b2",
          "commented_on": "5f992b5338f5f035f35911c5"
        },
        {
          "comment": "I like this product",
          "commented_by": "5f992b5338f5f035f35911a2",
          "commented_on": "5f992b5338f5f035f35911c5"
        },
        {
          "comment": "Great, I like it!",
          "commented_by": "5f992b5338f5f035f35911c8",
          "commented_on": "5f992b5338f5f035f35911c5"
        } 
                 
    ],
    "hasCommented": true,
    "comments_no": 3
}
{
    "_id": "5f992b5338f5f035f35911c5",
    "title": "Some title here..."
    "description": Some description here ...
    "price": 1000,
    "category": "Clothing",
    "type": "shoe",
    "comments": [ 
        {
          "comment": "Nice Product",
          "commented_by": { 
              "_id": "5f992b5338f5f035f35911b2",
              "firstName": "Jack",
              "lastName": "Sparrow" 
          },
          "commented_on": "5f992b5338f5f035f35911c5"
        },
        {
          "comment": "I like this product",
          "commented_by": { 
              "_id": "5f992b5338f5f035f35911a2",
              "firstName": "John",
              "lastName": "Doe" 
          },
          "commented_on": "5f992b5338f5f035f35911c5"
        },
        {
          "comment": "Great, I like it!",
          "commented_by": { 
              "_id": "5f992b5338f5f035f35911c8",
              "firstName": "Mary",
              "lastName": "Jane" 
          },
          "commented_on": "5f992b5338f5f035f35911c5"
        } 
                 
    ],
    "hasCommented": true,
    "comments_no": 3
}
当获得一个特定的产品时,我现在可以列出该产品的评论,但问题是在“评论人”部分列出的所有评论上,我需要用它填充它(需要名字、姓氏…)字段


你知道我该怎么做吗?

你所做的是正确的。在
产品
评论
之间进行查找后,您还需要进行另一次查找才能加入
用户

您需要添加以下阶段以实现您的目标

  • 展开到非结构化的
    注释[]
    数组
  • 查找
    加入
    用户
    集合
  • 由于lookup提供了一个数组,我们可以在安全操作符的帮助下使用
    $arrayElemAt
    获取数组的第一个元素
    $ifNull
    。(如果
    注释[]
    为空,则脚本抛出错误。要处理此错误,我们使用
    $ifNull
  • 我们已经解除了数组的结构,
    group
    帮助重新组合它
各阶段如下所示

  {
    $unwind: "$comments"
  },
  {
    $lookup: {
      from: "User",
      let: {
        id: "$comments.commented_by"
      },
      pipeline: [
        {
          $match: {
            $expr: {
              $eq: [
                "$_id",
                "$$id"
              ]
            }
          }
        },
        
      ],
      as: "comments.commented_by"
    }
  },
  {
    $addFields: {
      "comments.commented_by": {
        $ifNull: [
          {
            $arrayElemAt: [
              "$comments.commented_by",
              0
            ]
          },
          {}
        ]
      }
    }
  },
  {
    $group: {
      _id: "$_id",
      title: {
        $first: "$title"
      },
      hasCommented: {
        $first: "$hasCommented"
      },
      comments: {
        $push: "$comments"
      }
    }
  }
工作


注意:仅供参考,变量和集合名称可能不同。

这是否回答了您的问题:?