MongoDB 聚合:计算不同的字段

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18501064/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 13:23:38  来源:igfitidea点击:

MongoDB Aggregation: Counting distinct fields

mongodbaggregation-framework

提问by user1438162

I am trying to write an aggregation to identify accounts that use multiple payment sources. Typical data would be.

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

{
 account:"abc",
 vendor:"amazon",
}
 ...
{
 account:"abc",
 vendor:"overstock",
}

Now, I'd like to produce a list of accounts similar to this

现在,我想生成一个与此类似的帐户列表

{
 account:"abc",
 vendorCount:2
}

How would I write this in Mongo's aggregation framework

我将如何在 Mongo 的聚合框架中编写此内容

回答by user1438162

I figured this out by using the $addToSet and $unwind operators.

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

Mongodb Aggregation count array/set size

Mongodb 聚合计数数组/集合大小

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

Hope it helps someone

希望它可以帮助某人

回答by Mayur Kataria

I think its better if you execute query like following which will avoid unwind

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

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 } } }
);

Which will show you following result which is expected.

这将向您显示以下预期结果。

{ "_id" : "abc", "number" : 2 }

回答by Rahul

I do not see why somebody would have to use $group twice

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

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

This will work perfectly fine.

这将工作得很好。

回答by Hett

You can use sets

您可以使用 sets

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

回答by Anuj Gupta

This approach doesn't make use of $unwind and other extra operations. Plus, this won't affect anything if new things are added into the aggregation. There's a flaw in the accepted answer. If you have other accumulated fields in the $group, it would cause issues in the $unwind stage of the accepted answer.

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

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

回答by Amitesh

To identify accounts that use multiple payment sources:

要识别使用多个付款来源的帐户:

  1. Use grouping
  2. Use a match to filter count
  1. 使用分组
  2. 使用匹配来过滤计数

db.payment_collection.aggregate([ { $group: {"_id":"$account" , "number":{$sum:1}} }, { "$match": { "number": { "$gt": 1 } } } ])

db.payment_collection.aggregate([ { $group: {"_id":"$account" , "number":{$sum:1}} }, { "$match": { "number": { "$gt" : 1 } } } ])

回答by Abilash Raghu

db.UserModule.aggregate(
{ $group : { _id : { "companyauthemail" : "$companyauthemail", "email" : "$email" }, number : { $sum : 1 } } },
{ $group : { _id : "$_id.companyauthemail", number : { $sum : 1 } } }
);

回答by user3448195

An example

一个例子

db.collection.distinct("example.item").forEach( function(docs) {
    print(docs + "==>>" + db.collection.count({"example.item":docs}))
});