如何使用$和$或优化此查询

时间:2012-11-18 04:29:54

标签: mongodb

来自SQL我有这个搜索条件

WHERE (col1 LIKE "%foo%" OR col2 LIKE "%foo%") AND
      (col1 LIKE "%bar%" OR col2 LIKE "%bar%")

我想将其转换为MongoDB。

我想到了这个,希望在语义上相同的查询:

{
  $and: [
    {
      $or: [
        { col1: /.*foo.*/ },
        { col2: /.*foo.*/ }
      ]
    },
    {
      $or: [
        { col1: /.*bar.*/ },
        { col2: /.*bar.*/ }
      ]
    }
  ]
}

这是正确的方法还是可以改进? 有关索引的任何建议(如果它们可以使用的话)?

3 个答案:

答案 0 :(得分:0)

是的,这是为MongoDB实现该查询的正确方法。

如果您希望索引完全协助查询,则它必须是包含两个字段的compound index,因为MongoDB查询每个查询只能使用一个索引。所以像这样的指数:

db.coll.ensureIndex({col1: 1, col2: 1})

您可以使用explain()确认您的查询正在使用您期望的索引。

答案 1 :(得分:0)

这里有三个问题:

  • $and是两个评估的查询
  • $or是两个评估的查询
  • 没有预先固定的正则表达式

$and不使用多索引计划,只有一个索引计划,但是$或者使用单一复合索引这样做也没有那么多。

实际上没有索引会有帮助,因为MongoDB不能为没有预先加前缀的正则表达式使用索引。

因此,实际添加任何索引对此查询都没用。

无法以其当前形式优化此查询。

通常,这样的搜索的一种好​​方法是将您要搜索的单词拆分成可以直接搜索并编入索引的单词子文档。请查看:http://www.mongodb.org/display/DOCS/Full+Text+Search+in+Mongo示例。

使用此功能时,您可能会在单词数组中包含一个索引。 MongoDB应该能够将该索引用于整个查询($or两次)。

修改

此外,$or与您发布的内容有所不同。

您不需要$and和两个$or。您只需要一个$或多个条件:

再次编辑

我决定取出$或者完全取出。请注意,这使用索引不友好的正则表达式,但它仍然是一个有趣的概念。

{ col1: /.*(foo|bar).*/ , col2: /.*(bar|foo).*/ }

如果您想使用索引友好的东西,那么您将需要完全改变查询的工作方式,如上所述。

答案 2 :(得分:0)

andor查询以不同方式进行优化。直接从50 tips and tricks MongoDB引用:

  

提示#27:AND-queries应尽可能快地匹配   

  

提示#28:OR查询应尽快匹配   

因此,根据实际查询的复杂性和灵活性,您应该使foobar更通用,但尝试限制两个$or语句的结果。

希望有所帮助