每个字段/键的不同值的 mongodb 计数

是否有一个查询,用于计算数据库中字段包含多少不同的值。

我有一个领域的国家,有8种类型的国家价值观(西班牙,英国,法国等)

如果有人添加更多的文件与一个新的国家,我想查询返回9。

还有比分组计数更简单的方法吗?

237017 次浏览

MongoDB 有一个 distinct指令,它返回一个字段的不同值的数组; 您可以检查数组的长度来计数。

还有一个 shell db.collection.distinct()助手:

> db.countries.distinct('country');
[ "Spain", "England", "France", "Australia" ]


> db.countries.distinct('country').length
4

如 MongoDB 文件所述:

结果不得大于最大 BSON 大小(16MB)。如果结果超过最大 BSON 大小,则使用聚合管道使用 $group运算符检索不同的值,如 使用聚合管道检索不同的值所述。

你可以利用 Mongo Shell 扩展。是单人间。Js 导入,您可以将其附加到 $HOME/.mongorc.js,如果您也在 Node.js/io.js 中编写代码,也可以通过编程方式附加。

样本

对于每个不同的字段值,可选择通过查询筛选文档中的出现次数

> db.users.distinctAndCount('name', {name: /^a/i})

{
"Abagail": 1,
"Abbey": 3,
"Abbie": 1,
...
}

Field 参数可以是字段数组

> db.users.distinctAndCount(['name','job'], {name: /^a/i})

{
"Austin,Educator" : 1,
"Aurelia,Educator" : 1,
"Augustine,Carpenter" : 1,
...
}

下面是使用聚合 API 的示例。为了使情况复杂化,我们从文档的数组属性中按不区分大小写的单词进行分组。

db.articles.aggregate([
{
$match: {
keywords: { $not: {$size: 0} }
}
},
{ $unwind: "$keywords" },
{
$group: {
_id: {$toLower: '$keywords'},
count: { $sum: 1 }
}
},
{
$match: {
count: { $gte: 2 }
}
},
{ $sort : { count : -1} },
{ $limit : 100 }
]);

产生诸如

{ "_id" : "inflammation", "count" : 765 }
{ "_id" : "obesity", "count" : 641 }
{ "_id" : "epidemiology", "count" : 617 }
{ "_id" : "cancer", "count" : 604 }
{ "_id" : "breast cancer", "count" : 596 }
{ "_id" : "apoptosis", "count" : 570 }
{ "_id" : "children", "count" : 487 }
{ "_id" : "depression", "count" : 474 }
{ "_id" : "hiv", "count" : 468 }
{ "_id" : "prognosis", "count" : 428 }

对于 MongoDb3.4.4和更新的版本,您可以利用 一个 href = “ https://docs.mongodb.com/Manual/reference/Operator/cluster/arrayToObject/”rel = “ norefrer”> $arrayToObject 操作符和 < a href = “ https://docs.mongodb.com/Manual/reference/Operator/attaging/replaceRoot/”rel = “ noReferrer”> $replaceRoot 管道来获取计数。

例如,假设您有一个具有不同角色的用户集合,并且希望计算角色的不同计数。您需要运行以下聚合管道:

db.users.aggregate([
{ "$group": {
"_id": { "$toLower": "$role" },
"count": { "$sum": 1 }
} },
{ "$group": {
"_id": null,
"counts": {
"$push": { "k": "$_id", "v": "$count" }
}
} },
{ "$replaceRoot": {
"newRoot": { "$arrayToObject": "$counts" }
} }
])

输出示例

{
"user" : 67,
"superuser" : 5,
"admin" : 4,
"moderator" : 12
}

为了在收藏中找到不同的 field_1,我们也需要一些 WHERE条件,比如:

db.your_collection_name.distinct('field_1', {WHERE condition here and it should return a document})

因此,从一个年龄大于25岁的集合中找出数字不同的 names:

db.your_collection_name.distinct('names', {'age': {"$gt": 25}})

希望能有帮助!

我使用以下查询:

var collection = "countries"; var field = "country";
db[collection].distinct(field).forEach(function(value){print(field + ", " + value + ": " + db[collection].count({[field]: value}))})

产出:

countries, England: 3536
countries, France: 238
countries, Australia: 1044
countries, Spain: 16

这个查询首先区分所有值,然后为每个值计算出现的次数。

我想要一个更简洁的答案,我想出了以下使用 总量及组别的文档

db.countries.aggregate([{"$group": {"_id": "$country", "count":{"$sum": 1}}}])

如果你使用 MongoDB 3.4 + ,你可以在聚合管道中使用 $count:

db.users.aggregate([
{ $group: { _id: '$country' } },
{ $count: 'countOfUniqueCountries' }
]);