MongoDB聚合:计算不同的字段

use*_*162 26 mongodb aggregation-framework

我正在尝试编写一个聚合来识别使用多个支付来源的帐户.典型的数据是.

{
 account:"abc",
 vendor:"amazon",
}
 ...
{
 account:"abc",
 vendor:"overstock",
}
Run Code Online (Sandbox Code Playgroud)

现在,我想制作一个类似于此的帐户列表

{
 account:"abc",
 vendorCount:2
}
Run Code Online (Sandbox Code Playgroud)

我将如何在Mongo的聚合框架中编写它

use*_*162 60

我通过使用$ addToSet和$ unwind运算符来解决这个问题.

Mongodb聚合计数数组/集大小

db.collection.aggregate([
{
    $group: { _id: { account: '$account' }, vendors: { $addToSet: '$vendor'} }
},
{
    $unwind:"$vendors"
},
{
    $group: { _id: "$_id", vendorCount: { $sum:1} }
}
]);
Run Code Online (Sandbox Code Playgroud)

希望它可以帮助某人

  • 这个答案解决了大数据的情况:http://stackoverflow.com/a/24770233/139721 (3认同)
  • 这可能适用于集合的热情足够小的集合,但对于大数据场景这不起作用(想象一下,如果您有数十万个独特的供应商)。 (2认同)
  • @JerryChin 可以在管道中使用运算符 `$size` /sf/ask/1295074511/#49210341 (2认同)

May*_*ria 22

我认为如果你执行下面的查询会更好,这将避免放松

db.t2.insert({_id:1,account:"abc",vendor:"amazon"});
db.t2.insert({_id:2,account:"abc",vendor:"overstock"});


db.t2.aggregate(
{ $group : { _id : { "account" : "$account", "vendor" : "$vendor" }, number : { $sum : 1 } } },
{ $group : { _id : "$_id.account", number : { $sum : 1 } } }
);
Run Code Online (Sandbox Code Playgroud)

这将显示以下预期的结果.

{ "_id" : "abc", "number" : 2 }
Run Code Online (Sandbox Code Playgroud)


Rah*_*hul 15

我不明白为什么有人必须两次使用$ group

db.t2.aggregate([ { $group: {"_id":"$account" , "number":{$sum:1}} } ])
Run Code Online (Sandbox Code Playgroud)

这将完美无缺.

  • 我认为他们正在寻找"独特"的数量. (17认同)
  • 这个答案是错误的,因为它假设没有帐户会两次拥有相同的供应商(即它假设每个帐户的文档数量与不同供应商的数量相同。完全错误。 (5认同)
  • 这是“不同计数”吗? (4认同)

Het*_*ett 15

您可以使用 sets

db.test.aggregate([
    {$group: { 
      _id: "$account", 
      uniqueVendors: {$addToSet: "$vendor"}
    }},
    {$project: {
      _id: 1, 
      vendorsCount: {$size: "$uniqueVendors"}
    }}
]);
Run Code Online (Sandbox Code Playgroud)


Anu*_*pta 5

此方法不使用 $unwind 和其他额外操作。另外,如果将新内容添加到聚合中,这不会影响任何内容。接受的答案有一个缺陷。如果 $group 中有其他累积字段,则会在接受答案的 $unwind 阶段导致问题。

db.collection.aggregate([{
    "$group": {
        "_id": "$account",
        "vendors": {"$addToSet": "$vendor"}
    }
},
{
    "$addFields": {
        "vendorCount": {
            "$size": "$vendors"
        }
    }
}])
Run Code Online (Sandbox Code Playgroud)

  • 这个答案与 18 个月前添加的 @Hett 的答案相同。 (3认同)