首页 > 解决方案 > 如何$查找/填充数组内的嵌入式文档?

问题描述

如何$查找/填充数组内的嵌入式文档?

下面是我的架构的样子。

const CommentSchema = new mongoose.Schema({
    commentText:{
        type:String,
        required: true
    },
    arrayOfReplies: [{  
        replyText:{
            type:String,
            required: true
        },
        replier: [{
            type: mongoose.Schema.Types.ObjectId,
            ref: 'User',
            required: true,
        }],
    }],
});

如何获得如下所示的查询结果:

[    
    {    
        commentText: 'comment text',
        arrayOfReplies: [
            {
                replyText: 'replyText',
                replier: {
                    username:"username"
                    bio: 'bio'
                }
            }
        ]
    }
]

我正在尝试填充replier数组中的字段arrayOfReplies。我已经尝试了以下聚合查询的几种变体。那些已经接近我想要达到的目标有一个缺点。没有回复的评论有一个arrayOfReplies包含空对象的数组。即arrayOfReplies: [{}],本质上意味着数组不为空。

我曾尝试在其他管道运算符中使用add fields$mergeObjects,但无济于事。

如何 $lookup/populate数组replier内的文档?arrayOfReplies

下面是我的聚合查询主要部分的模板,减去尝试填充replier文档。

Comment.aggregate([
    {$unwind: {"path": '$arrayOfReplies', "preserveNullAndEmptyArrays": true }},
    {$lookup:{from:"users",localField:"$arrayOfReplies.replier",foreignField:"_id",as:"replier"}},
    {$unwind: {"path": "$replier", "preserveNullAndEmptyArrays": true }},

    {$group: {
        _id : '$_id',
        commentText:{$first: '$commentText'},
        userWhoPostedThisComment:{$first: '$userWhoPostedThisComment'},
        arrayOfReplies: {$push: '$arrayOfReplies' },
    }},

标签: mongodbmongoosemongodb-queryaggregation-framework

解决方案


您可以使用以下聚合:

操场

Comment.aggregate([
  {
    $unwind: {
      "path": "$arrayOfReplies",
      "preserveNullAndEmptyArrays": true
    }
  },
  {
    $lookup: {
      from: "users",
      localField: "arrayOfReplies.replier",
      foreignField: "_id",
      as: "replier"
    }
  },
  {
    $addFields: {
      "arrayOfReplies.replier": {
        $arrayElemAt: [
          "$replier",
          0
        ]
      }
    }
  },
  {
    $project: {
      "replier": 0
    }
  },
  {
    $group: {
      _id: "$_id",
      "arrayOfReplies": {
        "$push": "$arrayOfReplies"
      },
      commentText: {
        "$first": "$commentText"
      }
    }
  }
]);

推荐阅读