【问题标题】:Unify all Highlighting results in a single consolidated result ElasticSearch将所有突出显示结果统一在一个合并的结果中 ElasticSearch
【发布时间】:2018-06-06 14:34:08
【问题描述】:

我们正在使用 Elasticsearch percolator。

我们试图在单个文本中显示所有突出显示的项目,但不会得到很多不同的结果。但据我们所知,这在当前的 ElasticSearch 版本中是不可能的。尽管我们found 认为这可以通过使用(升级版)Lucene 来实现,因为它支持统一的突出显示结果,但我们没有时间这样做。

我们需要快速简单的想法来解决这个问题。我们发现这可以通过在之后添加相应的 html 装饰来完成,但我们正在考虑列出每个结果的每个单词,然后使用该列表查找原始文本中的所有项目到 order 结果出现在它们的位置。

问题是,将所有 ElasticSearch 突出显示结果统一到一个合并结果中的最正确和更简单的过程是什么?

谢谢

【问题讨论】:

    标签: elasticsearch highlight elasticsearch-percolate


    【解决方案1】:

    在完成这个小项目后,我们选择了 python 方法。

    主要问题是 ElasticSearch 提供突出显示结果的方式:它是为搜索引擎设计的,因此在具有突出显示结果的文本片段之间,而不是提供完整的文本。

    出于这个原因,我们选择通过后处理来突出显示结果,而不是使用 ElasticSearch 的突出显示:我们获得搜索结果,我们通过 python 处理它们,最后我们提供带有突出显示的单词的完整文本。

    一、获取查询搜索结果的函数:

    def get_response(client, index, query):
        s = Search().using(client).index(index).query("percolate", field='query', document={'title': query})
        response = s.execute()
        # get all matches: s.scan() https://elasticsearch-dsl.readthedocs.io/en/latest/search_dsl.html#pagination
        return response
    

    Percolator 是当前elasticsearch-dsl-py 发布版本中不存在的类,因此,现在我们实现它:

    class Percolate(Query):
        name = 'percolate'
    

    其次,我们得到所有的terms和它们的文档id:

    def get_highlighted_term(response):
        dic_results = defaultdict(list)
        for hit in response:
            for query in hit.query:
                if query == 'span_term':
                    dic_results[hit.query.span_term.title].append(hit.doc_id)
                if query == 'span_near':
                    phrase = ''
                    for title in hit.query.span_near.clauses:
                        phrase += title.span_term.title + ' '
                    dic_results[phrase[:-1]].append(hit.doc_id)
        return dic_results
    

    我们使用字典是因为它的多功能性:标题/术语作为键,文档的标识符作为其值;这样在文本高亮时更容易获取对应的值。

    最后,我们得到结果文本:

    def get_highlighted_text(dic_results, text):
        for term, doc_ids in dic_results.items():
            insensitive_term = re.compile(re.escape(term), re.IGNORECASE)
            if len(doc_ids) > 1:
                result_text = "<ul id='multiple-links'>"
                for doc_id in doc_ids:
                    result_text += "<li><a href='http://localhost/{0}'>{1}</a></li>".format(doc_id, term)
                result_text += "</ul>"
                text = insensitive_term.sub(result_text, text)
            else:
                text = insensitive_term.sub('<a href="http://localhost/{}">\g<0></a>'.format(doc_ids[0]), text)
        return text
    

    这次我们将常用术语的文档 ID 作为下拉列表处理。我们还使用正则表达式进行替换。

    这是我们的方法,你可以找到完整的项目代码here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多