我有一份文件:
{
"_id": ObjectId("5324d5b30cf2df0b84436141"),
"value": 0,
"metaId": {
"uuid": "8df088b2-9aa1-400a-8766-3080a6206ed1",
"domain": "domain1"
}
}
此外,我确保了此类型的索引:
ensureIndex({"metaId.uuid" : 1})
现在有两个问题:
db.test.find({"metaId" : {"uuid" : "8df088b2-9aa1-400a-8766-3080a6206ed1"}}).explain()
"cursor" : "BasicCursor"
没有使用索引!
db.test.find({"metaId.uuid" : "8df088b2-9aa1-400a-8766-3080a6206ed1"}).explain()
"cursor" : "BtreeCursor metaId.uuid_1"
使用了索引!
有没有办法让两个查询都使用索引?
答案 0 :(得分:2)
首先,以下文件:
{
"_id": ObjectId("5324d5b30cf2df0b84436141"),
"value": 0,
"metaId": {
"uuid": "8df088b2-9aa1-400a-8766-3080a6206ed1",
"domain": "domain1"
}
}
与查询不匹配:
db.test.find({
"metaId": {
"uuid": "8df088b2-9aa1-400a-8766-3080a6206ed1"
}
});
因为,它通过" metaId"的价值来查询。必须完全匹配:
{
"uuid": "8df088b2-9aa1-400a-8766-3080a6206ed1",
"domain": "domain1"
}
在这种情况下,您可以在" metaId"上使用索引。
答案 1 :(得分:1)
有一个已知问题,SERVER-2953。如果你愿意,你可以投票。
与此同时,你可以这样做:
{
"value": 0,
"metaId": [{
"uuid": "8df088b2-9aa1-400a-8766-3080a6206ed1",
"domain": "domain1"
}]
}
使用略微不同的查询表单,然后选择 索引:
db.test.find(
{"metaId" : {
"$elemMatch": {
"uuid" : "8df088b2-9aa1-400a-8766-3080a6206ed1"
}
}}
).explain()
实际上,查询 也会将索引与您当前的数据格式相匹配。但是它不会返回结果。但是使用这种形式的数据它将返回一个匹配。
通常最好将数组元素与"包含的" 子文档一起使用,即使它只是一个。这样可以实现更灵活的搜索,特别是如果您希望将来扩展子文档中的不同字段键。