在检查$ exists运算符是否存在时,MongoDB可以使用索引吗?

时间:2011-11-18 00:29:01

标签: mongodb indexing

如果我的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将用于此查询的索引?

3 个答案:

答案 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