我们有一个简单的网页,用户可以在其中提供一些输入和查询数据库。我们目前使用mongodb但希望迁移到elasticsearch,因为查询速度更快。
有一些必需的搜索字段,例如开始和结束日期,以及一些可选的搜索字段,例如匹配条目的搜索字符串,或父搜索字符串,以匹配父条目。父子关系只是通过包含每个条目的祖先ID的字段来描述。
问题如下:如果同时提供搜索和父搜索字符串,是否有一种方法可以在执行查询之前知道哪个查询应该先执行,以便更快地提供结果并提高性能? / p>
例如,可能是特定的父搜索只导致2个docs / parent条目,然后我们可以获取与搜索字符串匹配的所有子项。在这种情况下,我们应首先执行父查询,然后执行条目查询。
一个选项是获取两个查询的计数,然后先执行计数最小的查询,但这个解决方案是否更糟,因为查询将被执行两次?一次为计数,一次为实际查询。
还有其他方法可以解决这个问题吗?
PS。我们使用elasticsearch v1.7
示例
假设用户想要搜索与以下字段匹配的所有条目。
searchString:type:BLOCK AND name:test
parentSearchString:name:parentTest AND NOT type:BLOCK
这意味着我们要么必须
parentSearchString
匹配的所有条目(父级)并存储其ID。然后,我们必须获取与searchString
匹配的所有条目,并且还必须包含ancestors
字段中的任何父ID。OR
searchString
匹配的所有条目并存储所有ancestors
个ID。然后获取与parentSearchString
匹配的所有条目,其ID为ancestors
ID之一。为了澄清,父条目和子条目具有完全相同的结构并且位于相同的索引中。我们不能有不同的索引,因为pare-child关系可以嵌套10次,因此一个条目既可以是父条目也可以是子条目。条目看起来或多或少像:
{
id: "e32452365321",
name: "name",
type: "type",
ancestors: "id1 id2 id3" // stored in node as an array of ids
}
答案 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 /术语发送第二个查询。虽然获取两个查询的计数并不像您想象的那么糟糕,因为结果很可能仍然被缓存,它实际上有帮助吗?因为如果你从小孩到父母,你必须计算祖先(字段值),而不是实际的文件数。
我认为,最昂贵的操作通常是从磁盘中获取结果源。无论你走哪条路,你都应该只在第一个查询中获取你需要的东西。所以你的选择是:
ancestors
上的terms filter。不幸的是,我无法帮助你,因为我没有足够的经验来比较这些方法的速度。我的猜测是,id过滤器一般来说可能更快。但那只是猜测...