elasticsearch:决定首先运行哪个查询

时间:2017-07-19 13:53:18

标签: elasticsearch

我们有一个简单的网页,用户可以在其中提供一些输入和查询数据库。我们目前使用mongodb但希望迁移到elasticsearch,因为查询速度更快。

有一些必需的搜索字段,例如开始和结束日期,以及一些可选的搜索字段,例如匹配条目的搜索字符串,或父搜索字符串,以匹配父条目。父子关系只是通过包含每个条目的祖先ID的字段来描述。

问题如下:如果同时提供搜索和父搜索字符串,是否有一种方法可以在执行查询之前知道哪个查询应该先执行,以便更快地提供结果并提高性能? / p>

例如,可能是特定的父搜索只导致2个docs / parent条目,然后我们可以获取与搜索字符串匹配的所有子项。在这种情况下,我们应首先执行父查询,然后执行条目查询。

一个选项是获取两个查询的计数,然后先执行计数最小的查询,但这个解决方案是否更糟,因为查询将被执行两次?一次为计数,一次为实际查询。

还有其他方法可以解决这个问题吗?

PS。我们使用elasticsearch v1.7

示例

假设用户想要搜索与以下字段匹配的所有条目。

searchString:type:BLOCK AND name:test

parentSearchString:name:parentTest AND NOT type:BLOCK

这意味着我们要么必须

  1. 获取与parentSearchString匹配的所有条目(父级)并存储其ID。然后,我们必须获取与searchString匹配的所有条目,并且还必须包含ancestors字段中的任何父ID。
  2. OR

    1. 获取与searchString匹配的所有条目并存储所有ancestors个ID。然后获取与parentSearchString匹配的所有条目,其ID为ancestors ID之一。
    2. 为了澄清,父条目和子条目具有完全相同的结构并且位于相同的索引中。我们不能有不同的索引,因为pare-child关系可以嵌套10次,因此一个条目既可以是父条目也可以是子条目。条目看起来或多或少像:

      {
        id: "e32452365321",
        name: "name",
        type: "type",
        ancestors: "id1 id2 id3" // stored in node as an array of ids
      }
      

1 个答案:

答案 0 :(得分:0)

首先,如果可能的话,我会建议你升级你的Elasticsearch版本。自1.7以来发生了很多事,说实话,我不知道下一篇文章中所写的内容是否适用于这样一个旧版本(可能不是)。

但是对于您的实际问题:希望我能正确理解您,但您尝试估算Elasticsearch的查询成本是多少?好吧,你不必。如果您在一个嵌套查询中提供所有“查询”,Elasticsearch将为您执行此操作:https://www.elastic.co/blog/elasticsearch-query-execution-order

关于速度,还有一点我可以提及:计算分数确实需要时间。因此,如果排序不是基于elasticsearch _score,则需要使用布尔过滤器查询。这也适用,如果您只想按父匹配的_score排序,那么您可以将子查询放入过滤器。

<强>更新

感谢你的例子,我现在看到了问题。不幸的是,自我参照的亲子关系{EbleSearch not supported,所以你的方法可能是正确的。您可能需要查看有关application-joins的文档的简短章节。

所以是的,通常,您希望以尽可能少的ID /术语发送第二个查询。虽然获取两个查询的计数并不像您想象的那么糟糕,因为结果很可能仍然被缓存,它实际上有帮助吗?因为如果你从小孩到父母,你必须计算祖先(字段值),而不是实际的文件数。

我认为,最昂贵的操作通常是从磁盘中获取结果源。无论你走哪条路,你都应该只在第一个查询中获取你需要的东西。所以你的选择是:

  • 仅获取父匹配的ID,然后在第二个查询中使用ancestors上的terms filter
  • 或者,只获取子匹配的祖先字段,并在第二个查询中使用id filter

不幸的是,我无法帮助你,因为我没有足够的经验来比较这些方法的速度。我的猜测是,id过滤器一般来说可能更快。但那只是猜测...