与 mongoDb 和 mongoose 聚合后填充单个 ObjectId 引用

Posted

技术标签:

【中文标题】与 mongoDb 和 mongoose 聚合后填充单个 ObjectId 引用【英文标题】:Populate a single ObjectId reference after aggregating with mongoDb and mongoose 【发布时间】:2021-03-19 05:11:55 【问题描述】:

我试图在聚合和计数后填充。

这些是我的模型:

用户日志

const UserLog = new Schema(
  
    title: 
      type: String,
      required: true,
      trim: true,
    ,
    article: 
      type: mongoose.Schema.ObjectId,
      ref: 'Article',
      required: true,
    ,
    user: 
      type: mongoose.Schema.ObjectId,
      ref: 'User',
      required: true,
    ,
  ,
   timestamps: true, toJSON:  virtuals: true , toObject:  virtuals: true  
);

文章

const Article = new Schema(
  
    title: 
      type: String,
      required: true,
      trim: true,
    ,
    content: 
      type: String,
      required: true,
    ,
  ,
   timestamps: true, toJSON:  virtuals: true , toObject:  virtuals: true  
);

我正在运行这样的查询:

export const getCountByArticle = async () => 
  const articles = await UserLog.aggregate([
    
      $group:  _id: '$article', count:  $sum: 1  ,
    ,
  ]);
  return articles;
;

查询返回:

[
        
            "_id": "5fcbc12dd895b528289723e6",
            "count": 1
        ,
        
            "_id": "5fccefc375c47a3fd49c083d",
            "count": 2
        
    ],

问题是我想用实际文章“填充”_id 字段。我试过 $lookup,但它返回一个包含所有文章的数组,我不想要那个。放松对我也不起作用。下面是我真正想要的结果。

[
        
            "_id": "5fcbc12dd895b528289723e6",
            "title": "Title",
            "content": "contentcontentcontentcontentcontentcontentcontentcontentcontentcontentcontentcontentcontentcontentcontentcontentcontentcontentcontentcontentcontent",
            "count": 1
        ,
        
            "_id": "5fccefc375c47a3fd49c083d",
            "title": "Title",
            "content": "contentcontentcontentcontentcontentcontentcontentcontentcontentcontentcontentcontentcontentcontentcontentcontentcontentcontentcontentcontentcontent",
            "count": 2
        
    ],

我真的希望有人可以帮助我。提前致谢。

【问题讨论】:

【参考方案1】:

您可以在聚合操作中的 $group 阶段之后添加 $lookup 管道步骤,该步骤与 Mongoose 使用 $replaceRoot 中的 $mergeObjects 填充和重塑文档流类似,以合并来自$group 和 $lookup 数组:

export const getCountByArticle = async () => 
    const articles = await UserLog.aggregate([
         $group:  
            _id: '$article', count:  $sum: 1  
         ,
         $lookup: 
            from: 'articles',
            localField: '_id',    
            foreignField: '_id',  
            as: 'articles'
         ,
         $replaceRoot:  
            newRoot:  
                $mergeObjects: [ 
                     $arrayElemAt: [ '$articles', 0 ] , 
                    '$$ROOT' 
                ] 
             
         ,
         $project:  articles: 0  
    ]).exec();
  
    return articles;
;

【讨论】:

【参考方案2】:

使用$lookupfor MongoDB > 3.2

 
   "$lookup" : 
        from: "name of lookup collection",
        localField: "field in the input collection",
        foreignField: "field in the lookup collection",
        as: "field name for the output documents"
     
 

【讨论】:

以上是关于与 mongoDb 和 mongoose 聚合后填充单个 ObjectId 引用的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB/Mongoose - 与 geoNear 和子文档的聚合

mongoDB (mongoose增删改查聚合索引连接备份与恢复监控等等)

[第16期] mongoDB 干货笔记(mongoose/增删改查/聚合/索引/连接/备份与恢复/监控等)

使用聚合 mongodb mongoose 将集合子子文档与其他集合子文档连接起来

mongoDB,带有 $sum 和 $count 的 mongoose 聚合查询

mongoDB,带有 $sum 和 $count 的 mongoose 聚合查询