【问题标题】:Elasticsearch highlight matches in HTML without breaking syntaxElasticsearch 在不破坏语法的情况下突出显示 HTML 中的匹配项
【发布时间】:2016-11-29 21:31:49
【问题描述】:

Elasticsearch 有一个内置的“突出显示”功能,允许您在结果中标记匹配的术语(比乍听起来更复杂,因为查询语法可以包括近似匹配等)。

我有 HTML 字段,当我打开高亮显示时,Elasticsearch 会覆盖整个 HTML 语法。

我可以在以这种方式突出显示时使其支持 HTML/HTML 安全吗?

我希望突出显示应用于 HTML 文档中的文本,而不是突出显示与搜索匹配的任何 HTML 标记,即搜索“p”可能会突出显示 <p>p</p> -> <p><mark>p</mark></p>

我的字段被索引为“type: string”。

documentation says:

编码器:

编码器参数可用于定义如何突出显示 文本将被编码。它可以是默认(无编码)或 html (如果您使用 html 高亮标签,将转义 html)。

.. 但是 HTML 转义了我已经 HTML 编码的字段,进一步破坏了事情。

这里有两个示例查询

  1. 使用默认编码器:

高亮标签被插入到其他标签中,即<p> -> <<tag1>p</tag1>>:

curl -XPOST -H 'Content-type: application/json' "http://localhost:7200/myindex/_search?pretty" -d '
{
  "query": { "match": { "preview_html": "p" } },
  "highlight": {
    "pre_tags" : ["<tag1>"],
    "post_tags" : ["</tag1>"],
    "encoder": "default",
    "fields": {
      "preview_html" : {}
    }
  },
  "from" : 22, "size" : 1
}'

GIVES:
...
      "highlight" : {
        "preview_html" : [ "<<tag1>p</tag1> class=\"text\">TOP STORIES</<tag1>p</tag1>><<tag1>p</tag1> class=\"text\">Middle East</<tag1>p</tag1>><<tag1>p</tag1> class=\"text\">Syria: Developments in Syria are main story in Middle East</<tag1>p</tag1>>" ]
      }

...
  1. 使用html 编码器:

现有的 HTML 语法被 elasticsearch 转义,这会破坏事物,即&lt;p&gt; -> &amp;lt;&lt;tag1&gt;p&lt;/tag1&gt;&amp;gt;:

curl -XPOST -H 'Content-type: application/json' "http://localhost:7200/myindex/_search?pretty" -d '
{
  "query": { "match": { "preview_html": "p" } },
  "highlight": {
    "pre_tags" : ["<tag1>"],
    "post_tags" : ["</tag1>"],
    "encoder": "html",
    "fields": {
      "preview_html" : {}
    }
  },
  "from" : 22, "size" : 1
}'

GIVES:
...
      "highlight" : {
        "preview_html" : [ "&lt;<tag1>p</tag1> class=&quot;text&quot;&gt;TOP STORIES&lt;&#x2F;<tag1>p</tag1>&gt;&lt;<tag1>p</tag1> class=&quot;text&quot;&gt;Middle East&lt;&#x2F;<tag1>p</tag1>&gt;&lt;<tag1>p</tag1> class=&quot;text&quot;&gt;Syria: Developments in Syria are main story in Middle East&lt;&#x2F;<tag1>p</tag1>&gt;" ]
        }
      }

...

【问题讨论】:

  • 你想像&lt;tag1&gt;&lt;p&gt;&lt;/tag1&gt;一样拥有它吗?
  • 另外,能否提供preview_html字段的映射关系?
  • @AndreiStefan:我已经更新了问题文本来回答你的两个问题。
  • 很抱歉,您没有回答问题。 type: string 是该字段的唯一详细信息吗?您没有定义或类似的分析器?另外,您说 不要突出显示与搜索匹配的任何 HTML 标记,但在示例中您要突出显示 html 标记 (&lt;p&gt;&lt;mark&gt;p&lt;/mark&gt;&lt;/p&gt;),那么它是哪一个?
  • 1.是的,“类型:字符串”是我为该列提供 ES 的唯一映射指令。任何分析器都将是默认分析器。 2. 示例显示文本中的“p”用“”突出显示,但 HTML 标记名称

    中的“p”未突出显示(与第一个示例查询相比问题)。

标签: elasticsearch highlight


【解决方案1】:

实现此目的的一种方法是在分析preview_html 字段时使用html_strip char filter
这将确保在 html 标记上不会发生匹配,因此突出显示将忽略它,如下例所示。

例子:

put test
{
   "settings": {
      "index": {
         "analysis": {
            "char_filter": {
               "my_html": {
                  "type": "html_strip"
               }
            },
            "analyzer": {
               "my_html": {
                  "tokenizer": "standard",
                  "char_filter": [
                     "my_html"
                  ],
                  "type": "custom"
               }
            }
         }
      }
   }
}

put test/test/_mapping
{
   "properties": {
      "preview_html": {
         "type": "string",
         "analyzer": "my_html",
         "search_analyzer": "standard"
      }
   }
}

put test/test/1
{
    "preview_html": "<p> p </p>"
}

post test/test/_search
{
   "query": {
      "match": {
         "preview_html": "p"
      }
   },
   "highlight": {
      "fields": {
         "preview_html": {}
      }
   }
}

结果

 "hits": [
         {
            "_index": "test",
            "_type": "test",
            "_id": "1",
            "_score": 0.30685282,
            "_source": {
               "preview_html": "<p> p </p>"
            },
            "highlight": {
               "preview_html": [
                  "<p> <em>p</em> </p>"
               ]
            }
         }
      ]

【讨论】:

  • 谢谢,这看起来很理想。我会做一些测试,看看我能不能让它工作。
  • 这将正确地仅突出显示查询匹配项,但在生成突出显示片段时,来自字段源的 html 可能格式错误。您可以使用包含大量 html 文本的字段对此进行测试。据我所知,获得干净的 html 突出显示的唯一方法是将提取的 html 文本存储在单独的字段中并突出显示。同样,这只是突出显示片段的问题。突出显示整个 html 字段不会出现格式错误的 html 问题,因为所有标签都将被关闭。这是 elasticsearch 和 solr 的问题。
  • 是的,我同意这是一个限制。但是,在 ES 5.4 中,如果您不仅想要一个片段,boundary-scanners 可能会有所帮助。不过我还没有测试过。
猜你喜欢
  • 2015-06-05
  • 2018-04-19
  • 1970-01-01
  • 2016-08-24
  • 2020-08-19
  • 2012-07-15
  • 2021-12-19
  • 1970-01-01
  • 2017-07-17
相关资源
最近更新 更多