这个查询有多可行

时间:2014-01-13 10:10:06

标签: mongodb

假设您有一组具有以下结构的文档:

_id
A_id = ObjectId
B_id = ObjectId
C_id = ObjectId
+ other stuff

假设您拥有大约1亿到10亿个文档的集合。我必须运行查询, 返回所有文档,使得A_id,B_id或C_id在ObjectId的某个列表中,比如L = [ObjectId]

这样的事情:

{ '$or' : [ { 'A_id' : { '$in' : L}},
{ 'B_id' : { '$in' : L}},
{ 'C_id' : { '$in' : L}} ]
}
问:运行此类查询是否可行?在mongodb上运行此类查询是否正常? 问:单个服务器需要多长时间,水平扩展数据库需要多长时间?

2 个答案:

答案 0 :(得分:0)

这是一个可行的查询。

真正的问题是“这是一个好的查询吗?”

该问题的答案极其依赖于许多变量。

首先,我假设您在查询的每个字段都有索引。我也假设查询保持原样,没有排序。应该注意的是,存在一些问题导致优化器在此处使用排序索引:https://jira.mongodb.org/browse/SERVER-1205

假设您有A_idB_idC_id上的索引,MongoDB基本上会执行3次查询并合并重复项,然后再返回结果。

这意味着对于小$or个查询,它可能在数据库(或mongos)本身内更快,因为您不必在应用程序中自己合并重复项,这不仅会节省网络流量,对$or的每个条款的结果进行代价高昂的迭代。

对于像这样的小$or,查询是好的。它不是世界上最好的查询,但如果你别无选择,只会做$or

  

问:单个服务器需要多长时间,水平扩展数据库需要多长时间?

不确定这里是否有人可以回答这个问题。它取决于架构,$in的大小等等。

答案 1 :(得分:0)

运行该查询肯定是可行的。但是,您可能需要考虑一种可以更容易搜索的替代结构。

而不是

_id
A_id = ObjectId
B_id = ObjectId
C_id = ObjectId
+ other stuff

您可能希望将其重组为:

_id
idList = [ 
   { k: 'A', v: AObjectId },
   { k: 'B', v: BObjectId },
   { k: 'C', v: CObjectId }
]
+ other stuff

通过使用带有keyvalue字段的子对象的数组,您可以索引value字段,这样您就可以只执行一次有效的查询:

{ 'idList' : { $in : [listToCheck] } }