自定义Elasticsearch的搜索算法

时间:2012-10-02 00:25:10

标签: java lucene elasticsearch apache-tika

我最初尝试将相似的帖子发布到elasticsearch邮件列表(https://groups.google.com/forum/?fromgroups=#!topic/elasticsearch/BZLFJSEpl78),但没有得到任何有用的回复,所以我虽然尝试了Stack Overflow。这是我关于SO的第一篇文章,如果它不适合它所要达到的模具那么道歉。

我目前正在与一所大学合作,帮助他们实施测试套件,以进一步完善他们一直在进行的一些研究。他们的研究基于动态模式搜索。在花了一些时间评估各种开源搜索解决方案后,我决定将elasticsearch作为基础平台,我想知道最好的方法是什么。我花了大约一个星期来研究elasticsearch文档和代码本身,还阅读Lucene的文档,但我很难看到明确的前进方向。

该项目的目标是为研究提供一个软件,他们可以使用这些软件来插入搜索算法的修订版以进行测试和改进。他们希望能够使用JVM支持的Java以外的其他语言编写可插入算法,如Groovy,Python或Closure,但这并不是一项艰难的要求。其中一部分是为他们提供运行查询的前端,查看输出和管理界面,以便将文档添加到索引中。由于功能强大且完整的REST API,我对所有这些感到满意。我不太确定如何继续实施可插拔搜索算法。

研究人员的算法需要4个输入才能起作用:

  1. 查询字词。
  2. Word(term)x跨索引的文档矩阵。
  3. 索引中的文档x字(术语)矩阵。
  4. 索引中的Word(术语)频率列表。这就是整个索引中每个单词出现的次数。
  5. 出于他们的目的,文档不对应于实际的真实世界文档(他们实际上称之为文本事件)。相反,就目前而言,它对应于一个句子(具有可配置性也可能有用)。我认为处理这个问题的最好方法是将文档分解成句子(使用Apache Tika或类似的东西),将每个句子作为自己的文档放在索引中。我相信我可以在我使用mapper-attachement插件作为起点提供的Admin UI中执行此操作。缺点是在将文档提供给elasticsearch之前分解文档并不是一种非常可配置的方法。如果他们想要将分辨率更改为他们的算法,他们需要再次将所有文档重新添加到索引中。如果索引按原样存储完整文档,并且搜索算法可以选择在每个查询中使用什么分辨率,那么这将是完美的。我不确定它是否可能。

    下一个问题是如何获得他们需要的三个输入并将其传递到他们的可插拔搜索算法中。我真的在努力从这个开始。从看Luecene看,我需要提供自己的搜索/查询实现,但我不确定这是否正确。在elasticsearch网站上似乎也没有列出任何搜索插件,所以我甚至不确定它是否可行。这里重要的是,在使用模式对索引中的每个文档进行评分之前,算法需要在索引级别操作,并使用可用的查询项来生成其模式。据我所知,这意味着elasticsearch提供的脚本界面将没有任何用处。 elasticsearch指南中脚本界面的描述使其听起来像脚本在文档级而不是索引级操作。其他问题/考虑因素是能够以多种语言编写此算法(就像脚本界面一样),并能够增加REST API返回的内容,以便搜索包含算法生成的模式(我假设这意味着我需要定义自己的REST端点())。

    有人可以给我一些关于从哪里开始的建议吗?看起来我将不得不编写自己的搜索插件,它可以接受脚本作为它的核心算法。在将控制权传递给脚本之前,插件将负责组织我之前概述的4个输入。它还负责从脚本获取输出并通过它自己的REST API返回它。这看起来合乎逻辑吗?如果是这样,我该如何开始这样做?我需要查看哪些代码部分?

1 个答案:

答案 0 :(得分:0)

如果他们的算法有效,你应该为每个文档存储1个句子。如果他们改变模型,你可以随时重新索引。

Lucene非常善于找到比赛,所以我怀疑你的同事'算法将处理评分。 ElasticSearch支持自定义评分脚本。您可以将params传递给给定的评分脚本。您可以在ES中使用groovy进行脚本编写。 http://www.elasticsearch.org/guide/reference/modules/scripting.html

要在搜索算法中使用较大的数据结构,将这些数据结构作为参数传递是没有意义的,您可能会发现在评分脚本中使用其他数据源很有用。 例如Redis:http://java.dzone.com/articles/connecting-redis-elasticsearch