Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MongoDB在使用$exists运算符检查字段是否存在时是否可以使用索引?_Mongodb_Indexing - Fatal编程技术网

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上测试)