1

来自 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.*/ }
      ]
    }
  ]
}

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

4

3 回答 3

0

andor查询以不同的方式进行优化。直接引用MongoDB 的 50 个技巧和窍门

提示 #27:AND 查询应尽可能快地匹配

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

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

希望能帮助到你

于 2012-11-18T11:33:42.873 回答
0

您在这里遇到三个问题:

  • $and是两个评估的查询
  • $or是两个评估的查询
  • 无前缀正则表达式

$and不使用多索引计划,仅使用单个索引计划,但是 $or 在此处使用单个复合索引并没有太大帮助。

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

所以实际上添加任何索引对于这个查询都是没有用的。

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

通常,进行此类搜索的一种好​​方法是将要搜索的单词拆分为可以直接搜索和索引的单词子文档。看看:http ://www.mongodb.org/display/DOCS/Full+Text+Search+in+Mongo的例子。

使用它时,您可能会在单词数组上放置一个索引,仅此而已。MongoDB 应该能够在整个查询中使用该索引(两次以上$or)。

编辑

此外,$or作品与您发布的方式不同。

你不需要$and和 两个$ors。您只需要一个具有多重条件的 $or:

再次编辑

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

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

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

于 2012-11-18T09:52:23.820 回答
0

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

如果你想要一个索引来完全辅助查询,它需要是一个包含这两个字段的复合索引,因为 MongoDB 查询每个查询只能使用一个索引。所以像这样的索引:

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

您可以通过使用确认您的查询使用的是您期望的索引explain()

于 2012-11-18T05:12:23.417 回答