MongoDB子文档的快速计数-可能是索引
我在MongoDB Atlas集群上使用MongoDB 4.0(3个副本-1个碎片) 假设我有一个包含多个文档的集合 这些文档中的每一个都包含一个子文档数组,这些子文档表示特定年份的城市以及其他信息。示例文档如下所示(为了简化示例,我删除了不必要的信息): 我有一个年和月的复合指数。计算姓名和年份组合出现次数的最快方法是什么 我已经尝试了以下聚合:MongoDB子文档的快速计数-可能是索引,mongodb,b-tree,Mongodb,B Tree,我在MongoDB Atlas集群上使用MongoDB 4.0(3个副本-1个碎片) 假设我有一个包含多个文档的集合 这些文档中的每一个都包含一个子文档数组,这些子文档表示特定年份的城市以及其他信息。示例文档如下所示(为了简化示例,我删除了不必要的信息): 我有一个年和月的复合指数。计算姓名和年份组合出现次数的最快方法是什么 我已经尝试了以下聚合: [{$unwind: { path: '$cities' }}, {$group: { _id: { name: 'cities.n
[{$unwind: {
path: '$cities'
}}, {$group: {
_id: {
name: 'cities.name',
year: '$cities.year'
},
count: {
$sum: 1
}
}}, {$project: {
count: 1,
name: '$_id.name',
year: '$_id.year',
_id: 0
}}]
我尝试的另一种方法是以下形式的map reduce——map reduce的性能稍好一些,所需时间减少了30%
地图功能:
function m() {
for (var i in this.cities) {
emit({
name: this.cities[i].name,
year: this.cities[i].year
},
1);
}
}
reduce函数(也尝试用长度替换sum,但令人惊讶的是sum更快):
mongoshell中的函数调用:
db.test.mapReduce(m,r,{out:"mr_test"})
现在我在问自己——有可能访问索引吗?据我所知,这是一个B+树,它保存指向磁盘上相关文档的指针,因此从技术角度来看,我认为有可能遍历索引树的所有叶子,只计算指针?有人知道这是否可能吗
有人知道另一种高性能解决方法吗?(由于软件的其他依赖性,不可能更改设计,我们在一个非常大的数据集上运行此功能)。有没有人可能有通过碎片解决这类任务的经验?在这种情况下,索引不会有很大帮助 MongoDB索引设计用于识别符合给定标准的文档 如果您在
{cities.name:1,cities.year:1}
本文件:
{_id:123,
cities:[
{name:"vienna",
year:1985
},
{name:"berlin",
year:2001
}
{name:"vienna",
year:1985
}
]}
vienna|1985
berlin|2001
在b-树中有两个参考本文档的条目:
{_id:123,
cities:[
{name:"vienna",
year:1985
},
{name:"berlin",
year:2001
}
{name:"vienna",
year:1985
}
]}
vienna|1985
berlin|2001
即使可以计算索引中特定键的发生率,也不一定对应
MongoDB不提供检查索引中原始项的方法,并且它明确拒绝在包含数组的字段上使用索引进行计数
MongoDB count命令和helper用于所有count文档,而不是其中的元素。正如您所注意到的,您可以展开数组并对聚合管道中的项进行计数,但此时您已经将所有文档加载到内存中,因此使用索引为时已晚