gpt4 book ai didi

基于查询语法未使用子文档的 MongoDB 索引

转载 作者:可可西里 更新时间:2023-11-01 10:42:21 27 4
gpt4 key购买 nike

我将 Meteor 与 MongoDB 一起使用,并处理这样的文档集合:

{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 中,这两种表示法是等价的,坦率地说,我希望数据库足够智能,能够弄清楚这两个查询词指的是同一个字段并使用适当的索引。

我对索引整个子文档的解决方法的担忧是,最终,该子文档可能包含更多我不需要索引的字段,而且浪费时间和 RAM 保存我不需要的索引项似乎不是最佳选择。

如果这不是错误,是否有办法让 Mongo 识别嵌套对象语法并正确使用索引?

最佳答案

我想我是在检查了 mongo 文档后才弄明白的。基本上, 两者在语义上存在差异。本质上,在查询 {c: {d: d1}} 的第一种形式中,mongo 假定您正在指定整个 子文档。因此,如果您有一个子文档 {c: {d: d1, e: e1}},它将不匹配。

OTOH,查询的第二种形式 {'c.d': d1} 暗示您只在子文档中的一个字段上指定匹配项。即使子文档有其他字段或整个子子文档,这也会匹配。

这种差异延伸到索引。 _ensureIndex({c: 1})_ensureIndex({'c.d': 1}) 是两个不同的索引,即使第一个索引整个子文档,如果您使用 c.d 表示法查询单个字段,则不会使用它。

关于基于查询语法未使用子文档的 MongoDB 索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36941593/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com