MongoDB 分组并按最大分组排序

huangapple go评论52阅读模式
英文:

mongo group and sort by largest groups

问题

以下是您提供的内容的翻译:

假设我有以下的文件结构,其中我保存了员工、他们所在的城市以及他们所在的公司:

{
    "name": "john",
    "city": "milan",
    "company": "apple"
},
{
    "name": "nicole",
    "city": "rome",
    "company": "microsoft"
}

我试图实现的目标,最好在一个请求内,是为我提供按城市和公司分别排名前 n 的群组。我想要得到排名前 n 的城市和他们工作的排名前 n 的公司。

例如:

[
    {
        "milan": 23,
        "rome": 21,
        "new york": 18,
        "berlin": 10
    },
    {
        "facebook": 10,
        "apple": 8,
        "amazon": 8,
        "google": 2
    }
]

我可以使用简单的聚合管道和 $sum,但那会扫描整个集合,不会给我排名前(最受欢迎)的结果。

英文:

Say I have the following documents structure where I keep employees, their respective location, and company they work for:

{
    "name": "john",
    "city": "milan",
    "company": "apple"
},
{
    "name": "nicole",
    "city": "rome",
    "company": "microsoft"
}

What I'm trying to achieve, ideally within one request, is to give me top n groups individually across city and company. I want to have top n cities and top n companies they work for.

For exmaple:

[
    {
        "milan": 23,
        "rome": 21,
        "new york": 18,
        "berlin": 10
    },
    {
        "facebook": 10,
        "apple": 8,
        "amazon": 8,
        "google": 2
    }
]

What I can do is simple aggregation pipeline with $sum but that scans the whole collection and does not give me top (most popular) results.

答案1

得分: 2

你可以在这种情况下使用 $facet,正如@user20042973在评论中提到的。
我使用了 kv 的格式,这样我就可以在以后使用 $arrayToObject 将其转换为对象。

db.collection.aggregate([
  {
    $facet: {
      cities: [
        { $group: { _id: "$city", v: { $sum: 1 } } },
        { $sort: { v: -1 } },
        { $limit: n },
        { $project: { k: "$_id", v: "$v", _id: 0 } }
      ],
      companies: [
        { $group: { _id: "$company", v: { $sum: 1 } } },
        { $sort: { v: -1 } },
        { $limit: n },
        { $project: { k: "$_id", v: "$v", _id: 0 } }
      ]
    }
  },
  { $project: { converted: [ { $arrayToObject: "$cities" }, { $arrayToObject: "$companies" } ] } },
  { $unwind: "$converted" },
  { $replaceRoot: { newRoot: "$converted" } }
])

playground

英文:

you can use $facet in this case as mentioned in the comment by @user20042973
i used the k and v format so that I can use $arrayToObject on a later stage to convert it to an object

db.collection.aggregate([
  {
    $facet: {
      cities: [
        { $group: { _id: "$city", v: { $sum: 1 } } },
        { $sort: { v: -1 } },
        { $limit: n },
        { $project: { k: "$_id", v: "$v", _id: 0 } }
      ],
      companies: [
        { $group: { _id: "$company", v: { $sum: 1 } } },
        { $sort: { v: -1 } },
        { $limit: n },
        { $project: { k: "$_id", v: "$v", _id: 0 } }
      ]
    }
  },
  { $project: { converted: [ { $arrayToObject: "$cities" }, { $arrayToObject: "$companies" } ] } },
  { $unwind: "$converted" },
  { $replaceRoot: { newRoot: "$converted" } }
])

playground

huangapple
  • 本文由 发表于 2023年6月12日 02:58:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/76452059.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定