如果我的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将用于此查询的索引?
不,没有办法告诉mongodb使用索引进行存在查询.索引与数据完全相关.由于$ exists仅与密钥(字段)相关,因此无法在索引中使用.
$ exists只验证文档中是否存在给定的键(或字段).
$ 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 } ]
希望能帮到你!
由于MongoDB 2.0 $exists
查询应该使用索引。不幸的是,此修复程序已在最新版本中消失,并将在MongoDB 2.5中修复