Elasticsearch具有内置的“突出显示”功能,该功能可让您在结果中标记匹配的词(比起初听起来更复杂,因为查询语法可能包含接近匹配等)。
我有HTML字段,当我打开突出显示功能时,Elasticsearch会遍历整个HTML语法。
以这种方式突出显示时,是否可以使其支持HTML / HTML安全?
我希望突出显示应用于HTML文档中的文本,而不是突出显示与搜索匹配的任何HTML标记,即搜索“ p”可能会突出显示<p>p</p>-> <p><mark>p</mark></p>。
<p>p</p>
<p><mark>p</mark></p>
我的字段被索引为“ type: string”。
type: string
该文件说:
编码器: 编码器参数可用于定义突出显示的文本的编码方式。它可以是默认值(无编码)或html(如果使用html突出显示标签,则将转义html)。
编码器:
编码器参数可用于定义突出显示的文本的编码方式。它可以是默认值(无编码)或html(如果使用html突出显示标签,则将转义html)。
..但HTML转义了我本来已经HTML编码的字段,使事情变得更糟。
这是两个示例查询
高亮标签插入其他标签内,即<p>-> <<tag1>p</tag1>>:
<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>>" ] } ...
html
Elasticsearch对现有的HTML语法进行了转义,从而破坏了工作,即<p>-> <<tag1>p</tag1>>:
<<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": "html", "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>>" ] } } ...
实现此目的的一种方法是在分析字段时使用html_strip char过滤器preview_html。 这样可以确保while匹配不会在html标记上发生,因此突出显示将忽略它,如下面的示例所示。
preview_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>" ] } } ]