Giant Elasticsearch查询

时间:2017-12-20 17:44:58

标签: apache-spark elasticsearch

我有一个必须和must_not项目列表,我目前在一个巨大的查询中有,但我想知道这是否是解决问题的最佳方法。

查询示例:

{"query":{ "bool" : { "must" : {"match" : {"tag":"apple"}}, "must_not": [{ 
 "match": { "city": "new york" }},{ "match": { "name": "pizza" }},...........
]}}}

我有470个必须的项目和485个must_not项目是白名单/黑名单类型的数据规则。分析内置于spark中,数据存储在弹性搜索中。我传递给spark的查询是一个查询,其中一个必须跟随所有485 must_not项。您可以猜测查询本身相当大,大约需要2秒才能返回结果。我正在为每个必须项目提交此类查询,因此传递了470个查询。此应用程序目前大约需要22分钟才能完成。

我的问题 - 这是解决这个问题的最佳方法吗?对于弹性搜索而言,这甚至是一个很好的问题,因为巨大的查询?我之前尝试在仅使用must_not数据传递查询后尝试使用数据预先形成spark连接,这需要比470个弹性搜索单个查询长得多。我使用广播散列连接,因为必须数据小于结果数据帧。

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

每次调用查询都会产生以下开销:

  • 查询准备和提交
  • Spark - 弹性搜索握手。
  • 查询弹性执行。(涉及索引扫描 等......)
  • 序列化和反序列化
  • 网络转移。

下面提出的解决方案将通过避免一些开销(下面列出)来提高性能。

  • 查询准备和提交
  • Spark - 弹性搜索握手。
  • 查询弹性执行。(涉及索引扫描 等......)

如果您不需要将单个查询执行的文档分开(470必须),理想的方法是使用OR运算符构建一个布尔术语,如@khachik建议的那样。

如果您需要分离,有两种可能的解决方案

解决方案1:

构建弹性查询以返回在匹配条件中具有must_not的脚本字段(以及您选择的字段)。在您的情况下,每个术语将有470个脚本字段,其中每个字段都是布尔类型。如果“必须”,则值为TRUE。术语存在其他错误。将结果缓存为rdd后,您可以使用您选择的过滤器运行多个查询。由于数据缓存在内存中,查询应该更快。

解决方案:2

首先使用must_not在弹性方执行查询。开发一个返回" TRUE"给[TOKEN,TAG_VALUE]。现在使用该函数将470个布尔列附加到RDD。缓存RDD。现在,您可以使用简单的过滤器运行查询来隔离数据。