MongoDB 不同的聚合
Posted
技术标签:
【中文标题】MongoDB 不同的聚合【英文标题】:MongoDB distinct aggregation 【发布时间】:2013-04-28 10:21:02 【问题描述】:我正在查询每个州的邮政编码最多的城市:
db.zips.distinct("state", db.zips.aggregate([
$group:
_id:
state: "$state",
city: "$city"
,
numberOfzipcodes:
$sum: 1
,
$sort:
numberOfzipcodes: -1
])
)
查询的聚合部分似乎工作正常,但是当我添加 distinct 时,我得到一个空结果。
这是因为我在 id 中有状态吗?我可以做类似distinct("_id.state
的事情吗?
【问题讨论】:
对于那些寻找如何使用 Mongo 的聚合来获得不同值的人,试试这个(灵感来自 dam1's answer 和 Mongo's documentation):db.collectionName.aggregate([$group: _id: null, uniqueValues: $addToSet: "$fieldName"])
【参考方案1】:
Distinct 和聚合框架不可互操作。
你只是想要:
db.zips.aggregate([
$group:_id:city:'$city', state:'$state', numberOfzipcodes:$sum:1,
$sort:numberOfzipcodes:-1,
$group:_id:'$_id.state', city:$first:'$_id.city',
numberOfzipcode:$first:'$numberOfzipcodes'
]);
【讨论】:
@alex23 Distinct 是一个完全不同的命令,它返回一个不同值的数组。与聚合框架完全不兼容 这是我之前的查询,但我需要获取每个州的不同城市而不是州 @Lemonio 重新添加了城市,现在应该会在每个州的每个城市中释放拉链 @sammaye 我认为这正是我以前所拥有的?我只想要每个州的拉链最多的城市,这就是我试图做不同的原因。这样我就得到了每个州的所有城市,这是我之前的查询 @Lemonio 好的,你需要做第二组,编辑,编辑:修复了一些其他错误编辑:等等【参考方案2】:您可以将$addToSet 与聚合框架一起使用来计算不同的对象。
例如:
db.collectionName.aggregate([
$group: _id: null, uniqueValues: $addToSet: "$fieldName"
])
或扩展以将您的唯一值放入适当的列表而不是空 _id 记录中的子文档:
db.collectionName.aggregate([
$group: _id: null, myFieldName: $addToSet: "$myFieldName",
$unwind: "$myFieldName" ,
$project: _id: 0 ,
])
【讨论】:
不是一个通用的解决方案,如果每个结果有大量唯一的邮政编码,这个数组会非常大。问题是获取每个州的大多数邮政编码的城市,而不是获取实际的邮政编码。如果给定城市有 10,000,000 个邮政编码,会发生什么? 刚刚看到这一点,它根本不会计算不同的对象,而是将对象明确地放入一个数组中,不仅如此,而且===
上的区别并不总是一个好的主意。相反,您可能希望对不同的值进行分组,计算该值存在的次数,此时您可以轻松添加一个阶段以将其总结为唯一对象的数量。作为一种计数方法,这在内存、资源和处理器方面效率非常低。
如果它为 OP 提供了一个实际的答案,而不仅仅是 group/addtoSet 使用的语法的一般示例,这可能是一个更好的答案。
似乎 pymongo 不支持它..【参考方案3】:
SQL 查询:(分组方式和不同的计数)
select city,count(distinct(emailId)) from TransactionDetails group by city;
等效的 mongo 查询如下所示:
db.TransactionDetails.aggregate([
$group:_id:"CITY" : "$cityName",uniqueCount: $addToSet: "$emailId",
$project:"CITY":1,uniqueCustomerCount:$size:"$uniqueCount"
]);
【讨论】:
这个解决方案更清晰,只选择总数。【参考方案4】:您可以在单个数组上调用$setUnion
,它还可以过滤欺骗:
$project: Package: 1, deps: '$setUnion': '$deps.Package'
【讨论】:
以上是关于MongoDB 不同的聚合的主要内容,如果未能解决你的问题,请参考以下文章
MongoDB $geoNear 聚合管道(使用查询选项和使用 $match 管道操作)给出不同的结果