【发布时间】:2014-05-08 11:25:17
【问题描述】:
为了从 MongoDB 中选择 100 个最新文档,其中每个文档由同一集合中具有相似字段的多个文档组成(在本例中为 timestamp),我使用以下系列查询Node.js:
return q.ninvoke(collection, 'aggregate',
[
{
$match : { active: true }
},
{
$limit : 100
},
{
$group : {
_id : "$timestamp",
mintime : {
$min : "$seconds"
},
timestamp : {
$first : "$timestamp"
},
data : {
$first : "$data"
}
}
}
]);
当集合中的文档少于$limit 时,这可以正常工作。当有更多时,它会选择最旧的文档(首先插入),而不是具有最高 timestamp 的文档(通常但不总是最后插入的文档)。
这是出乎意料的,因为文档被插入到具有以下确保索引的集合中:
collection.ensureIndex({
timestamp : -1,
seconds : -1,
active : -1
}, {
sparse : false
});
我的印象是timestamp 上的第一个索引-1 意味着它们按降序索引,导致集合中第一个$limit 文档始终是具有最高timestamp 的文档.
为什么这不能按预期工作?
我错了吗?
【问题讨论】:
-
你需要先排序才能得到想要的结果
-
@Sebastian 为什么?这意味着要对数千份文档进行分类。索引顺序是专门为防止这种开销而设计的,不是吗?
-
不,它的存在是为了提高排序效率。这并不意味着您的所有查询都会自动排序。要使用索引,您需要进行排序。
-
如果有限的选择不会自动限制在索引顺序中,那么为什么我们需要在索引中指定该顺序?
-
@Sebastian 如果仔细观察,问题显然在于
$match选择找不到索引。排序与此无关。我看到了诱惑,但很可能“时间戳”实际上反映了插入顺序。因此,如果有的话,那应该是复合索引的辅助键。
标签: javascript node.js mongodb mongodb-query aggregation-framework