我正在尝试使用多键索引来查找另一个键的最新记录。我似乎无法表现出色。
在伪sql中我会说
create table my_table (user_id int, post_time timestamp, content text);
create index my_index (user_id,post_time) on my_table;
然后我可以点击索引以找到每个用户的最新post_time
select user_id,max(post_time) from my_table group by user_id
即使拥有数百万条记录,所有数据都会很好,也很快,数据将来自索引,而我们根本就不会出现这种情况。
使用Mongo
db.my_table.ensureIndex( { user_id:1,post_time:1} )
并查询
db.my_table.aggregate( { $group:{ '_id':'$user_id', 'max':{ $max:'$post_time'} } )
但这并没有达到索引 - 它似乎做了一个(慢)表扫描。
{
"stages" : [
{
"$cursor" : {
"query" : {
},
"fields" : {
"post_time" : 1,
"user_id" : 1,
"_id" : 0
},
"plan" : {
"cursor" : "BasicCursor",
"isMultiKey" : false,
"scanAndOrder" : false,
"allPlans" : [
{
"cursor" : "BasicCursor",
"isMultiKey" : false,
"scanAndOrder" : false
}
]
}
}
},
{
"$group" : {
"_id" : "$user_id",
"max" : {
"$max" : "$post_time"
}
}
}
],
"ok" : 1
}
我需要做什么才能使此查询执行?我应该使用mongo更好的方法/数据结构吗?
答案 0 :(得分:1)
不幸的是,您创建的任何索引都无法涵盖您的aggregate
查询。
只有$match
,$sort
和$geoNear
阶段才能在管道开头出现时使用这些索引。
来自docs,
$match
和$sort
管道运营商可以利用索引 当它们出现在管道的开头时。版本2.4中的新功能:$geoNear
管道运算符利用地理空间索引。 使用$geoNear
时,$geoNear
管道操作必须显示为 聚合管道中的第一个阶段。 即使是管道 使用索引,聚合仍然需要访问实际 文件;即索引无法完全覆盖聚合管道。