使用 Elasticsearch,我可以为不同的匹配标记使用不同的 HTML 标签突出显示吗?

Posted

技术标签:

【中文标题】使用 Elasticsearch,我可以为不同的匹配标记使用不同的 HTML 标签突出显示吗?【英文标题】:With Elasticsearch, can I highlight with different HTML tags for different matched tokens? 【发布时间】:2021-05-13 12:11:05 【问题描述】:

目前正在学习 ES,但我非常热衷于实现这一点。

我知道您可以在查询中使用highlightpre_tagspost_tags 键以不同的标签突出显示不同的字段...但是是否可以提供标记- up 字符串,其中返回的片段对于每个单独的识别词都有不同的 html 颜色标记,例如使用simple query string?

所以我用“有趣的数据”查询并返回一个文档字段,如下所示:

the other day I was walking through the woods and I had an <font color="blue">interesting</font> 
thought about some <font color="red">data</font>

我的意思不仅仅是标签“无意识地”交替:同样,您可以使用Fast Vector Highlighter,例如:

"highlight": 
    "fields": 
        "description": 
            "pre_tags": ["<b>", "<em>"],
            "post_tags": ["</b>", "</em>"]

相反,我想要该字段

“其他数据日数据正在穿过一些有趣的树林 和data对一些数据有一个有趣的想法”

这样返回:

the other <font color="red">data</font> day <font color="red">data</font> was walking through some <font color="blue">
interesting</font> woods and <font color="red">data</font> had an <font color="blue">
interesting</font> thought about some <font color="red">data</font>

我以前使用 Lucene(即 Java)进行编码,并且我确实设法实现了这种东西,主要是跳过了一些障碍。

注意,对此的一个答案可能是“忘记 ES 返回标记的文本,只需使用 re.sub( r'\bdata\b', '&lt;font color="red"&gt;data&lt;/font&gt;', field_string ) 应用您自己的标签”。

这对于像这样的简单用例来说是可以的。但它不适用于词干分析器。例如,举一个法语例子:搜索查询是“changer élément”。我想要以下标记结果:

Les autres <font color="red">éléments</font> ont été <font color="blue">
changés</font> car on a appliqué un <font color="blue">changement</font> 
à chaque <font color="red">élément</font>

即“changer”、“changes”和“changement”都源于“chang”,而“élément”和“éléments”都源于“element”。因此,该字段的标准突出显示返回是:

Les autres <em>éléments</em> ont été <em>changés</em> car on a appliqué un 
<em>changement</em> à chaque <em>élément</em>

【问题讨论】:

【参考方案1】:

快速矢量荧光笔是一个很好的起点。我还没有使用法语工作,所以不要认为以下权威但基于内置的french analyzer,我们可以做这样的事情:

PUT multilang_index

  "mappings": 
    "properties": 
      "description": 
        "type": "text",
        "term_vector": "with_positions_offsets",
        "fields": 
          "french": 
            "type": "text",
            "analyzer": "french",
            "term_vector": "with_positions_offsets"
          
        
      
    
  

仅供参考,french 分析器可能是 reimplemented/extended as shown here。

摄取英语和法语示例后:

POST multilang_index/_doc

  "description": "the other data day data was walking through some interesting woods and data had an interesting thought about some data"


POST multilang_index/_doc

  "description": "Les autres éléments ont été changés car on a appliqué un changement à chaque élément"

我们可以像这样查询interesting data

POST multilang_index/_search

  "query": 
    "simple_query_string": 
      "query": "interesting data",
      "fields": [
        "description"
      ]
    
  ,
  "highlight": 
    "fields": 
      "description": 
       "type": "fvh",
       "pre_tags": ["<font color=\"red\">", "<font color=\"blue\">"],
       "post_tags": ["</font>", "</font>"]
      
    ,
    "number_of_fragments": 0
  

屈服

the other <font color="blue">data</font> day <font color="blue">data</font> 
was walking through some <font color="red">interesting</font> woods and 
<font color="blue">data</font> had an <font color="red">interesting</font>
thought about some <font color="blue">data</font>

同样适用于changer élément

POST multilang_index/_search

  "query": 
    "simple_query_string": 
      "query": "changer élément",
      "fields": [
        "description.french"
      ]
    
  ,
  "highlight": 
    "fields": 
      "description.french": 
       "type": "fvh",
       "pre_tags": ["<font color=\"red\">", "<font color=\"blue\">"],
       "post_tags": ["</font>", "</font>"]
      
    ,
    "number_of_fragments": 0
  

屈服

Les autres <font color="blue">éléments</font> ont été 
<font color="red">changés</font> car on a appliqué un 
<font color="red">changement</font> à chaque <font color="blue">élément</font>

在我看来,它的词干是正确的。


请注意,pre_tags 的顺序是根据 simple_query_string 查询中的令牌匹配第一个来执行的。查询changer élément 时,description 中的瓦éléments 匹配first,但导致它匹配的是第二个标记(élément),因此blue html 标记而不是red

【讨论】:

谢谢...对我来说,出于某种原因,这对我的实际索引(来自 dbase 表的 40000 条记录)没有产生任何影响。今天有点忙,但会尝试最简单的用例,也就是你上面所说的。 嗯,我只是按照上面的使用邮递员......结果就像你说的那样。杰出的。现在我必须尝试理解为什么使用 Python elasticsearch 模块做同样的事情似乎不起作用......! 不客气!我倾向于一有机会就使用低级查询,并且不太喜欢客户端库抽象。 我刚刚对elasticsearch 模块做了同样的事情:工作顺利。文档说这是围绕 ES REST API (elasticsearch-py.readthedocs.io/en/v7.11.0/#features) 的“非常薄的包装器”......我显然第一次做错了什么。我认为“低级”解决方案是使用requests,如果您使用的是 Python。 酷!是的,它非常“薄”——检查here 了解python 选项的my 细分。是的,requests & REST 将是“低级”方法。我在后端经常使用它,尤其是。当我缓存响应并赋予读取/查询权限时。

以上是关于使用 Elasticsearch,我可以为不同的匹配标记使用不同的 HTML 标签突出显示吗?的主要内容,如果未能解决你的问题,请参考以下文章

阔别港股五年的匹克体育,拿下3亿美元融资后回A股有望吗?

是否可以为Elasticsearch维护从FileBeat到LogStash的索引名?

如何从Apache Flink写入Elasticsearch

我可以在同一台机器上运行多个elasticsearch实例进行日志聚合吗?

使用 spring-data-elasticsearch 的多租户

使用JAVA在我的项目中实现Elasticsearch的最佳方法是什么? [关闭]