Mongodb 如何使用$and和$or优化此查询

Mongodb 如何使用$and和$or优化此查询,mongodb,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.*/ } ] },

来自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.*/ }
      ]
    }
  ]
}
这是正确的方法还是可以改进的?

关于索引的任何建议(如果可以使用的话)?

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

如果您希望索引能够完全帮助查询,那么它必须是包含这两个字段的索引,因为MongoDB查询只能在每个查询中使用一个索引。这样的索引:

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

您可以通过使用确认您的查询正在使用您期望的索引。

这里有三个问题:

  • $和
    是两个经过计算的查询
  • $或
    是两个经过计算的查询
  • 无预固定正则表达式
$和
不使用多索引计划,而仅使用单个索引计划。然而,$或在此处使用单个复合索引不会有多大帮助

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

因此,实际上添加任何索引对这个查询都是无用的

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

通常,这样做搜索的一个好方法是将正在搜索的单词拆分成一个子文档中的单词,这些单词可以直接搜索并编入索引。看一看:例如

当你使用它的时候,你可能会在单词数组中放置一个索引,就是它。MongoDB应该能够在整个查询中使用该索引(对于
$或
,使用两次)

编辑 另外,
$或
的工作方式也与您的发布方式不同

您不需要
$和
以及两个
$或
s。您只需要一美元或一个多条件:

重新编辑 我决定把那美元全部拿出来。注意,这使用了索引不友好的正则表达式,但它仍然是一个有趣的概念

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

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

查询以不同的方式进行优化。直接引自:

提示#27:和查询应尽可能少地匹配,并尽可能快地匹配 尽可能

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

因此,根据实际查询的复杂性和灵活性,您应该使
foo
bar
更通用,同时尽量限制
$或
语句的结果


希望它能有所帮助

MongoDB可以将索引用于非前缀正则表达式查询,但它的效率不如扫描和测试所有索引值。另外,我不认为这个简化的查询是相同的,因为
{col1:'foobar'}
与原始查询匹配,但与此不匹配。如果它必须扫描索引中的所有值,那么唯一真实的事情就是可能正在加载内存的值(如果该索引最近使用过,否则会导致值的页面错误)90%的情况下,索引在这里并没有真正的帮助。这取决于文档的大小,因为如果文档很大,那么索引仍然会有很大的帮助,因为只有索引需要加载到内存中。@JohnnyHK如果文档足够重要,查询已经被修改了