如何在猫鼬中使用 Group by 和 find ?

Saj*_*ran 6 javascript mongoose mongodb node.js

metadata我有一个名为“listing”的集合,其中包含和 等字段status。元数据是一个user内部包含对象的对象,并且status是一个字符串。

结构看起来像这样,

{ "status": "Active", "metadata": { "user": { "urlProfile": "", "averageRating": 5, "reviewCount": 2, "userId": "1244324" } } }

现在,状态字段具有诸如"Active"和 之类的值"Inactive"。我需要按这些状态进行分组并按用户 ID 进行过滤。所以我在助手中有一个函数,如下所示,

 query: function (model, conditon, options) {
            console.log(conditon, options);
            return new Promise(function (resolve, reject) {
                options = options || {};

                model.find(conditon, {}, options).exec(function (error, data) {
                    if (error) {
                        reject(error);
                    }
                    resolve(data);
                })
            })
        }
Run Code Online (Sandbox Code Playgroud)

问题是我如何传递组和用户 ID 并查询所需的数据。现在我的查询部分看起来像这样,

return dbService.query(sellerModel, {
                    'metadata.user.userId': userIdRetrieved
                }, {});
Run Code Online (Sandbox Code Playgroud)

我怎样才能通过条件分组?我寻找样本,到目前为止还没有找到任何解决方案。

样品采集 在此输入图像描述

预期输出:

[{
  "Status": "Active",
  "Results": {
    "user": {
      "urlProfile": "",
      "averageRating": 5,
      "reviewCount": 2,
      "userId": "1244324"
    }
  }
}
,
{
  "Status": "InActive",
  "Results": {
    "user": {
      "urlProfile": "",
      "averageRating": 5,
      "reviewCount": 2,
      "userId": "1244324"
    }
  }
}]
Run Code Online (Sandbox Code Playgroud)

chr*_*dam 6

为了获得所需的输出,您需要使用该aggregate方法,因为它提供了允许您聚合文档并返回所述结果的运算符。

考虑构建一个由一个阶段组成的管道,通过累加器、with以及使用或的组中的其他字段$group来聚合平均评级。您的 group by key 是一个包含两个字段 Status 和 userId 的子文档。$avgreviewCount$sum$first$last

最后$project一步将允许您将上述组聚合的输出重塑为所需的形式,并且该aggregate()方法返回一个查询,然后您可以调用exec()该查询来获取Promise.


为了解释上面的框架,请按照以下示例:

query: function (model, conditon, options) {
    console.log(conditon, options);
    options = options || {};
    return model.aggregate([
        { "$match": conditon },
        {
            "$group": {
                "_id": { 
                    "Status": "$status", 
                    "userId": "$metadata.user.userId" 
                },
                "urlProfile": { "$first": "$metadata.user.urlProfile" },
                "averageRating": { "$avg": "$metadata.user.averageRating" },
                "reviewCount": { "$sum": "$metadata.user.reviewCount" }
            }
        },
        {
            "$project": {
                "_id": 0,
                "Status": "$_id.Status",
                "Results": {
                    "user": {
                        "averageRating": "$averageRating",
                        "reviewCount": "$reviewCount",
                        "userId": "$_id.userId"
                    }
                }
            }
        }
    ]).exec();      
}
Run Code Online (Sandbox Code Playgroud)