MongoDB 根据查询语法未使用子文档的索引
MongoDB indexes on subdocuments not being used based on syntax of query
我正在使用带有 MongoDB 的 Meteor 和这样的文档集合:
{a: 'a1',
b: 'b1',
c: {
d: 'd1',
e: 'e1'
}
}
我最初创建的索引是这样的:
collection._ensureIndex({'c.d': 1});
和 运行 这样的查询:
collection.find({c: {d: 'd1'})
。这些 运行 非常慢,当我使用 explain() 进行调试时,我意识到它们没有使用索引。
OTOH,如果我 运行 这样的查询:
collection.find({'c.d': 'd1'})
,那么 Mongo 会 使用索引。
我现在更改了索引以索引整个子文档,即 collection._ensureIndex({c: 1})
,第一个查询现在命中索引。
我的问题是,这是错误还是功能?我的印象是,在 JSON 中,这两个表示法是等价的,而且非常 f运行kly,我希望数据库足够聪明,可以弄清楚这两个查询词指的是同一个字段并使用适当的索引。
我对索引整个子文档的解决方法的担忧是,最终,该子文档可能包含更多我不需要索引的字段,而且浪费时间和 RAM 保存我不需要的索引项似乎不是最佳选择.
如果这不是错误,是否有办法让 Mongo 识别嵌套对象语法并正确使用索引?
我想我是在查看了 mongo 文档后才弄明白的。基本上,是这两者之间的语义差异。本质上,在查询的第一种形式 {c: {d: d1}}
中,mongo 假设您指定的是 entire 子文档。因此,如果您有一个子文档 {c: {d: d1, e: e1}}
,它将不匹配。
OTOH,查询的第二种形式 {'c.d': d1}
意味着您只在子文档中的一个字段上指定匹配项。即使子文档有其他字段或整个子子文档,这也会匹配。
这种差异延伸到索引。 _ensureIndex({c: 1})
和 _ensureIndex({'c.d': 1})
是两个不同的索引,即使第一个索引整个子文档,如果您使用 c.d
符号查询单个字段,它也不会被使用。
我正在使用带有 MongoDB 的 Meteor 和这样的文档集合:
{a: 'a1',
b: 'b1',
c: {
d: 'd1',
e: 'e1'
}
}
我最初创建的索引是这样的:
collection._ensureIndex({'c.d': 1});
和 运行 这样的查询:
collection.find({c: {d: 'd1'})
。这些 运行 非常慢,当我使用 explain() 进行调试时,我意识到它们没有使用索引。
OTOH,如果我 运行 这样的查询:
collection.find({'c.d': 'd1'})
,那么 Mongo 会 使用索引。
我现在更改了索引以索引整个子文档,即 collection._ensureIndex({c: 1})
,第一个查询现在命中索引。
我的问题是,这是错误还是功能?我的印象是,在 JSON 中,这两个表示法是等价的,而且非常 f运行kly,我希望数据库足够聪明,可以弄清楚这两个查询词指的是同一个字段并使用适当的索引。
我对索引整个子文档的解决方法的担忧是,最终,该子文档可能包含更多我不需要索引的字段,而且浪费时间和 RAM 保存我不需要的索引项似乎不是最佳选择.
如果这不是错误,是否有办法让 Mongo 识别嵌套对象语法并正确使用索引?
我想我是在查看了 mongo 文档后才弄明白的。基本上,是这两者之间的语义差异。本质上,在查询的第一种形式 {c: {d: d1}}
中,mongo 假设您指定的是 entire 子文档。因此,如果您有一个子文档 {c: {d: d1, e: e1}}
,它将不匹配。
OTOH,查询的第二种形式 {'c.d': d1}
意味着您只在子文档中的一个字段上指定匹配项。即使子文档有其他字段或整个子子文档,这也会匹配。
这种差异延伸到索引。 _ensureIndex({c: 1})
和 _ensureIndex({'c.d': 1})
是两个不同的索引,即使第一个索引整个子文档,如果您使用 c.d
符号查询单个字段,它也不会被使用。