在MongoDb中将对象用作_id会导致查询时出现collscan

时间:2016-11-14 12:52:09

标签: mongodb

我在使用自定义对象作为MongoDb中的_id值时遇到了一些问题。

我在_id中存储的对象如下所示:

"_id" : {
    "EDIEL" : "1010101010101",
    "StartDateTicks" : NumberLong(636081120000000000)
}

现在,当我执行以下查询时:

.find({ 
        "_id.EDIEL": { $eq: "1010101010101" }, 
        "_id.StartDateTicks": { $gte: 636082776000000000, $lt: 636108696000000000 } 
}).explain()

我做了COLLSCAN。我无法弄明白为什么。是因为我没有使用对象查询_id对象吗?

有谁知道我在这里做错了什么? : - )

修改

尝试创建包含EDIELStartDateTicks字段的复合索引,再次运行查询,现在它使用索引而不是列扫描。虽然这有效,但仍然很好避免使用额外的索引并且只有_id(因为它基本上是一个“免费”索引)所以,问题仍然存在:为什么我不能查询_id.EDIEL_id.StartDateTicks并使用索引?

2 个答案:

答案 0 :(得分:0)

索引用于键而不是对象,因此当您将对象用于_id时,对象的索引不能用于您在对象字段上执行的特定查询。

这不仅适用于_id,也适用于子文档。

{
 "name":"awesome book",
 "detail" :{
   "pages":375,
   "alias" : "AB"
 }
}

现在,如果您有详细信息索引,并且您通过detail.pages或detail.alias进行查询,则无法使用详细信息索引,当然也不能用于范围查询。您需要在detail.pages和detail.alias上有索引。

当在对象上应用索引时,它维护对象的索引作为整体而不是每个字段,这就是对象字段上的查询不能使用对象索引的原因。

希望有所帮助

答案 1 :(得分:0)

您需要单独索引这两个字段,因为索引不能嵌入到文档中。因此,创建复合索引是唯一可用的选项,或者在字段上创建多个索引,而这些索引又使用交叉索引是您的选项。