Elasticsearch在不破坏语法的情况下突出显示HTML中的匹配项 [英] Elasticsearch highlight matches in HTML without breaking syntax

查看:64
本文介绍了Elasticsearch在不破坏语法的情况下突出显示HTML中的匹配项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Elasticsearch具有内置的突出显示功能,该功能使您可以在结果中标记匹配的词(比起初听起来更复杂,因为查询语法可以包含近义词等)。



我有HTML字段,当我打开突出显示功能时,Elasticsearch遍及HTML语法。



我可以使它成为HTML吗



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



我的字段被索引为 type:字符串



文档中的内容


编码器:

编码器参数可用于定义突出显示的
文本的编码方式。可以是默认值(无编码),也可以是html
(如果使用html突出显示标签,则将转义html)。


..但是HTML转义了我已经为HTML编码的字段,从而使事情更进一步。



这里有两个示例查询


  1. 使用默认编码器:

突出显示标签插入其他标签内,即< p> -> << tag1> p< / tag1>>

  curl -XPOST -H'内容类型:application / json' http:// localhost:7200 / myindex / _search?pretty -d '
{
query:{ match:{ preview_html: p}}},
highlight:{
pre_tags:[< ; tag1>],
post_tags:[< / tag1>],
encoder:默认,
fields:{
Preview_html:{}
}
},
from:22, size:1
}'

礼物:
...
highlight:{
previe w_html:[<<< tag1> p< / tag1> class = texttext> TOP STORIES< /< tag1> p< / tag1><< tag1> p< / tag1> class = \ text\< Middle East< /< tag1> p< / tag1><< tag1> p< / tag1> class = \ text\>叙利亚:叙利亚的事态发展是中东的主要故事< /< / tag1> p< / tag1>"]
}

...




  1. 使用 html 编码器:

elasticsearch对现有HTML语法进行了转义,从而破坏了内容,即< p> -> & lt;< tag1> p< / tag1& 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
}'

给予:
...
突出显示:{
preview_html:[& lt;<< tag1> p< / tag1> class ="文本"<<&#x2F;< tag1> p< / tag1><< tag1> p< / tag1> class =" text& gt;"中东<&#x2F;< tag1> p< / tag1><<< tag1> p< / tag1> class =& quot;文本& gt;叙利亚:叙利亚的事态发展是中东的主要故事$ b}
}

...


解决方案

一种实现此目的的方法是使用 html_strip字符过滤器,同时分析 preview_html 字段。

这样可以确保while匹配不会在html标记上发生



示例:

  put test 
{
settings:{
index:{
analysis:{
char_filter:{
my_html:{
type: html_strip
}
},
analyzer:{
my_html :{{
tokenizer:标准,
char_filter:[
my_html
],
type:自定义
}
}
}
}
}
}

放置测试/测试/映射
{
属性:{
preview_html:{
type:字符串,
analyzer: my_html,
search_analyzer:标准
}
}
}

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

测试/测试/搜索
{
query:{
match:{
preview_html: p
}
},
highlight:{
fields:{
preview_html:{}
}
}
}



结果



 命中:[
{
_index:测试,
_type:测试,
_id: 1,
_score:0.30685282,
_source:{
preview_html:< p> p< / p>
},
亮点:{
preview_html:[
&p; < em> p< / em> < / p>
]
}
}
]


Elasticsearch has a built-in "highlight" function which allows you to tag the matched terms in the results (more complicated than it might at first sound, since the query syntax can include near matches etc.).

I have HTML fields, and Elasticsearch stomps all over the HTML syntax when I turn on highlighting.

Can I make it HTML-aware / HTML-safe when highlighting in this way?

I'd like the highlighting to apply to the text in the HTML document, and not to highlight any HTML markup which has matched the search, i.e. a search for "p" might highlight <p>p</p> -> <p><mark>p</mark></p>.

My fields are indexed as "type: string".

The documentation says:

Encoder:

An encoder parameter can be used to define how highlighted text will be encoded. It can be either default (no encoding) or html (will escape html, if you use html highlighting tags).

.. but that HTML-escapes my already HTML-encoded field, breaking things further.

Here are two example queries

  1. Using the default encoder:

The highlight tags are inserted inside other tags, i.e. <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. Using the html encoder:

The existing HTML syntax is escaped by elasticsearch, which breaks things, i.e. <p> -> &lt;<tag1>p</tag1>&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;" ]
        }
      }

...

解决方案

One way to achieve this is to use the html_strip char filter while analyzing preview_html field.
This would ensure that while matches would not occur on html markup and hence highlighting would ignore it to as shown in the example below.

Example:

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": {}
      }
   }
}

Results

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

这篇关于Elasticsearch在不破坏语法的情况下突出显示HTML中的匹配项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆