假设您有一组具有以下结构的文档:
_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上运行此类查询是否正常?
问:单个服务器需要多长时间,水平扩展数据库需要多长时间?
答案 0 :(得分:0)
这是一个可行的查询。
真正的问题是“这是一个好的查询吗?”
该问题的答案极其依赖于许多变量。
首先,我假设您在查询的每个字段都有索引。我也假设查询保持原样,没有排序。应该注意的是,存在一些问题导致优化器在此处使用排序索引:https://jira.mongodb.org/browse/SERVER-1205
假设您有A_id
,B_id
和C_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
通过使用带有key
和value
字段的子对象的数组,您可以索引value
字段,这样您就可以只执行一次有效的查询:
{ 'idList' : { $in : [listToCheck] } }