MongoDB在使用$exists运算符检查字段是否存在时是否可以使用索引?
如果我的MongoDB在使用$exists运算符检查字段是否存在时是否可以使用索引?,mongodb,indexing,Mongodb,Indexing,如果我的用户集合中有如下数据: { name: '...', email: '...', ..., photos: { 123: { url: '...', title: '...', ... }, 456: { url: '...', title: '...', ... }, ... } } 我想找到哪个用户拥有照片id 127,然后我使用查询: db.users.find( {'photos.127': {'$exists' =>
用户
集合中有如下数据:
{ 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将用于此查询的索引?已更新:
似乎$exists
查询现在基于这些票据正确使用索引
&
旧答案:
不,无法告诉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})
您可以添加explain以查看查询是否使用索引。
这是我的结果,我的收藏的移动密钥与您的照片相似。id:
> 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
}
]
希望对大家有所帮助 $exists
查询应使用索引。不幸的是,此修复程序没有!!!我使用mongodb 2.4.3进行了测试,它使用了索引。请注意,不存在的字段在index.MongoDB 3.0.3:explain
中的值为Null,用于find({field:{$exists:1}})
和find({field:{$ne:Null}})
看起来它将使用索引,但是第二个查询会立即完成,第一个查询会出错(我猜是完全扫描)。这太糟糕了。键是数据,应该能够被索引。如果不能为对象编制索引,允许对象作为数据有点糟糕。$exists
现在使用索引(在mongo 3.2上测试)$exists
现在使用索引(在mongo 3.2上测试)