如果我的users
集合中的数据看起来像:
{ name: '...',
email: '...',
...,
photos: {
123: { url: '...', title: '...', ... },
456: { url: '...', title: '...', ... },
...
}
}
我想找到哪个用户拥有照片ID 127,然后我正在使用查询:
db.users.find( {'photos.127': {'$exists' => true} } );
我已经尝试过了,但似乎不可能让MongoDB为这个查询使用索引。我尝试的索引是:db.users.ensureIndex({photos:1});
。当我使用explain()
时,mongo告诉我它使用的是BasicCursor(即没有使用索引)。
是否可以创建mongo将用于此查询的索引?
答案 0 :(得分:10)
不,没有办法告诉mongodb使用索引进行存在查询。 索引与数据完全相关。由于 $ exists仅与密钥(字段)相关,因此无法在索引中使用。
$ exists仅验证文档中是否存在给定的键(或字段)。
答案 1 :(得分:5)
$ exists不会使用索引,但您可以将数据结构更改为
photos: [
{id:123, url: '...', title: '...', ... },
{id:456, url: '...', title: '...', ... },
...
]
然后使用
db.users.ensureIndex({photos.id:1})
为照片ID创建索引。
看来我错了,事实上,你可以强制你的$ exists查询使用你的索引。 让我们继续使用上面的结构,但你的照片ID肯定不是包含在内的,也就是说 一些文档会有关键的' id'有些人不会。然后你可以在上面创建稀疏索引:
db.users.ensureIndex({'photos.id': 1}, {'sparse': true})
然后像这样查询:
db.users.find({'photos.id': {$exists: true}}).hint({'photos.id': 1})
您可以添加解释以查看查询是否使用索引。 这是我的结果,我的收藏品的移动钥匙与你的照片类似。:
> db.test.count()
50000
> db.test.find({'mobile': {$exists: true}}).hint({'mobile': 1}).explain()
{
"cursor" : "BtreeCursor mobile_1",
"nscanned" : 49999,
"nscannedObjects" : 49999,
"n" : 49999,
"millis" : 138,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
"mobile" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
}
}
> db.test.getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"ns" : "test.test",
"name" : "_id_"
},
{
"v" : 1,
"key" : {
"mobile" : 1
},
"ns" : "test.test",
"name" : "mobile_1",
"sparse" : true,
"background" : true
}
]
希望能帮到你!
答案 2 :(得分:5)
Since MongoDB 2.0 $exists
查询应使用索引。不幸的是,此修复程序有disappeared in the newest version and will be fixed in MongoDB 2.5