使用mongo max / min的多键索引 - 查找给定键的最新记录

时间:2015-02-05 20:01:10

标签: mongodb

我正在尝试使用多键索引来查找另一个键的最新记录。我似乎无法表现出色。

在伪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更好的方法/数据结构吗?

1 个答案:

答案 0 :(得分:1)

不幸的是,您创建的任何索引都无法涵盖您的aggregate查询。

只有$match$sort$geoNear阶段才能在管道开头出现时使用这些索引。

来自docs

  

$match$sort管道运营商可以利用索引   当它们出现在管道的开头时。版本2.4中的新功能:   $geoNear管道运算符利用地理空间索引。   使用$geoNear时,$geoNear管道操作必须显示为   聚合管道中的第一个阶段。 即使是管道   使用索引,聚合仍然需要访问实际   文件;即索引无法完全覆盖聚合管道。