Mongoose 在使用 $facet 进行聚合时如何使用 populate()?

Posted

技术标签:

【中文标题】Mongoose 在使用 $facet 进行聚合时如何使用 populate()?【英文标题】:Mongoose how to use populate() when making aggregation with $facet? 【发布时间】:2019-07-31 07:53:32 【问题描述】:

我有一个包含如下数据的集合


  "_id": ObjectId("5c630163b5284c5e6fb163d2"),
  "createdDate": ISODate("2019-02-12T17:24:51.844Z"),
  "year": 2004,
  "vehicleMake": ObjectId("5bcc8fdefdc6ed2b6733b478"),
  "vehicleModel": ObjectId("5bcc8fe0fdc6ed2b6733b88d") 

我正在尝试像这样获得方面聚合:

Vehicle.model.aggregate([
      $match:  year: 2015  ,
      $facet: 
         vehicleMake: [ $group:  _id: '$vehicleMake', count:  $sum: 1 ,  $sort:  count: -1, _id: -1 ], 
         vehicleModel: [ $group:  _id: '$vehicleModel', count:  $sum: 1 ,  $sort:  count: -1, _id: -1 ], 
         year: [ $group:  _id: '$year', count:  $sum: 1 ,  $sort:  _id: -1, _id: -1 ], 
         yearRange: [  $bucketAuto:  groupBy: '$year',  buckets: 5  ],
     
   
])

我的结果是这样的:

[
  
    "vehicleMake": [
      
        "_id": "5bcc8fdefdc6ed2b6733b4d5",
        "count": 1
      ,
      
        "_id": "5bcc8fdefdc6ed2b6733b4cf",
        "count": 1
      ,
      
        "_id": "5bcc8fdefdc6ed2b6733b4c7",
        "count": 1
      
    ],
    "vehicleModel": [
      
        "_id": "5bcc8fe1fdc6ed2b6733bb7a",
        "count": 1
      ,
      
        "_id": "5bcc8fe0fdc6ed2b6733b6ab",
        "count": 1
      ,
      
        "_id": "5bcc8fe0fdc6ed2b6733b65d",
        "count": 1
      
    ],
    "year": [
      
        "_id": 2015,
        "count": 3
      
    ],
    "yearRange": [
      
        "_id": 
          "min": 2015,
          "max": 2015
        ,
        "count": 3
      
    ]
  
]

请告诉我如何使用 populate() 从引用的集合(vehicleMake 和 vehicleModel)中获取数据以获取名称属性而不是 ObjectId 并获得类似这样的结果:

    "vehicleMake": [
      
        "_id": "Audi",
        "count": 1
      ,
      
        "_id": "BMW",
        "count": 1
      
    ]

或者也许有比 populate() 更好的选择?

【问题讨论】:

【参考方案1】:

您在架构中引用模型的名称,然后调用填充

Check this answer

【讨论】:

我在模型模式中有引用,当我使用 find() 操作调用 populate() 时没有问题。我的问题是如何使用 populate() 和 aggregate() 操作。【参考方案2】:

好的,我找到了解决方案。相反 populate() 有 &lookup 操作,最后我的工作聚合看起来像这样:

Vehicle.model.aggregate([
                 $match:  year: 2015  ,
                 $facet: 
                    vehicleMake: [
                       $lookup:  from: 'vehiclemakes', localField: 'vehicleMake', foreignField: '_id', as: 'makes' ,
                       $group:  _id: '$makes.name', count:  $sum: 1 ,  $sort:  _id: 1, count: -1 
                    ], 
                    vehicleModel: [ $group:  _id: '$vehicleModel', count:  $sum: 1 ,  $sort:  count: -1, _id: -1 ], 
                    year: [ $group:  _id: '$year', count:  $sum: 1 ,  $sort:  _id: -1, _id: -1 ], 
                    yearRange: [  $bucketAuto:  groupBy: '$year',  buckets: 5  ],
                
              
            ])

【讨论】:

以上是关于Mongoose 在使用 $facet 进行聚合时如何使用 populate()?的主要内容,如果未能解决你的问题,请参考以下文章

SQL (Hive):在使用 GROUP BY 进行聚合时使用窗口函数

在 Google BigQuery 中进行聚合时是不是可以运行计算

进行聚合时如何忽略数据框中的特定列

在 SQLite 中计算多个聚合时可以消除子查询吗?

Hive 在使用 case 语句和聚合时按列分组出错

ImportError:导入聚合时DLL加载失败:找不到指定的模块