mongodb count 每个字段/键的不同值的数量
Posted
技术标签:
【中文标题】mongodb count 每个字段/键的不同值的数量【英文标题】:mongodb count num of distinct values per field/key 【发布时间】:2013-02-02 04:28:52 【问题描述】:是否有一个查询来计算一个字段在 DB 中包含多少不同的值。
f.e 我有一个国家/地区字段,有 8 种国家/地区值(西班牙、英国、法国等)
如果有人添加了更多包含新国家/地区的文档,我希望查询返回 9。
还有比分组计数更简单的方法吗?
【问题讨论】:
你看过aggregation框架吗? 或map-reduce? MongoDB select count(distinct x) on an indexed column - count unique results for large data sets 的可能重复项。我在那里发布了我的答案。 【参考方案1】:MongoDB 有一个distinct
command,它返回一个字段的不同值的数组;您可以检查数组的长度以进行计数。
还有一个shell db.collection.distinct()
助手:
> db.countries.distinct('country');
[ "Spain", "England", "France", "Australia" ]
> db.countries.distinct('country').length
4
如 MongoDB 文档中所述:
结果不得大于最大 BSON 大小 (16MB)。如果您的结果超过最大 BSON 大小,请使用聚合管道使用
$group
运算符检索不同的值,如 Retrieve Distinct Values with the Aggregation Pipeline 中所述。
【讨论】:
如果你的不同值的数量太高,这真的不起作用......如果你正在查看世界上不同的人的名字或其他东西。你有一个可以扩展的答案吗? 1+ 表示长度。我正在努力寻找类似的东西。谢谢。 我不知道他们为什么不在那里使用 count() @MarianKlühspies - 因为它只是一个 javascript 数组,它使用 length 属性来计算元素的数量。 @rohitcoder 如果您有数百万或数十亿个文档要迭代不同的值,我建议发布一个新问题,其中包含您的环境和用例的详细信息。我希望您将使用比 2013 年 2 月的讨论更现代的 MongoDB 版本,当时 MongoDB 2.2 是最新的服务器版本并且刚刚引入了聚合框架:)。我编辑了我的答案以包含来自distinct
文档的注释,该文档建议将聚合框架用于更大的结果集,但在现代版本的 MongoDB 中还有其他方法和运算符可用。【参考方案2】:
您可以利用Mongo Shell Extensions。这是一个单独的 .js 导入,您可以将其附加到您的 $HOME/.mongorc.js
,或者以编程方式(如果您也在 Node.js/io.js 中进行编码)。
示例
对于每个不同的字段值,统计在文档中出现的次数,可选地通过查询过滤
>
db.users.distinctAndCount('name', name: /^a/i)
"Abagail": 1,
"Abbey": 3,
"Abbie": 1,
...
字段参数可以是字段数组
>
db.users.distinctAndCount(['name','job'], name: /^a/i)
"Austin,Educator" : 1,
"Aurelia,Educator" : 1,
"Augustine,Carpenter" : 1,
...
【讨论】:
如何在节点中导入这个?require("./script.js")
,我想
对,但我无法获得里面的功能。我该如何使用它们。它们被定义为 db.protoptype.distinctAndCount
repo 的自述文件中有一个操作方法部分(RTFM!1!!1!)基本上,将.mongorc.js
file 放入您的主目录。完成。【参考方案3】:
这里是使用聚合 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
【讨论】:
登录只是为了+这个答案。谢谢!顺便说一句,如果你在一个独特的领域做,只需删除展开线。 @RichieRich,unwind
是必要的,因为代码正在对与 distinct
工作方式匹配的数组字段的各个值进行分组。
@Paul Richie 所说的是,如果分组只是“常规”字段(字符串、整数等)完成,那么您不需要展开步骤。对不对?
@guyarad unwind
在处理数组时是必需的。
+1 的答案,正是我正在做的事情,但不同有其自身的魅力,但这只是黄金:) - 无论如何,我必须阅读更多关于聚合以实现所需的集合过滤数据的结果【参考方案4】:
在 MongoDb 3.4.4 和更高版本中,您可以利用 $arrayToObject
运算符和 $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
【讨论】:
这不是问题的答案,但它仍然很有帮助。我想知道这与.distinct()
相比表现如何。
谢谢!完全按照我需要的方式工作。【参考方案5】:
要在集合中的 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)
希望对你有帮助!
【讨论】:
【参考方案6】:我使用这个查询:
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
此查询首先区分所有值,然后计算每个值的出现次数。
【讨论】:
你能告诉我如何在 php laravel 中编写同样的查询吗? 这个查询中的主机是什么? @HeenaPatil 好收获!我在查询中有两个错误,我现在修复了它。hosts
是我在我的数据库中收藏的名称......对此感到抱歉。我还修复的另一个问题尝试调用db.collection
,我将其修复为db[collection]
。谢谢!【参考方案7】:
我想要一个更简洁的答案,我使用aggregates and group 的文档提出了以下内容
db.countries.aggregate(["$group": "_id": "$country", "count":"$sum": 1])
【讨论】:
以上是关于mongodb count 每个字段/键的不同值的数量的主要内容,如果未能解决你的问题,请参考以下文章
python| MongoDB聚合(countdistinctgroupMapReduce)
MongoDB:如何为集合中的每个文档设置一个等于另一个字段值的新字段[重复]