Elasticsearch:在使用html_strip过滤器无效的文档索引文档之前剥离HTML标记

时间:2016-05-20 16:49:24

标签: html elasticsearch filter full-text-search mapping

鉴于我在自定义分析器中指定了我的html strip char过滤器

何时我使用html内容索引文档

然后我希望html脱离索引内容

从索引中检索返回的文档时不包含hmtl

实际: 索引文档包含html 检索到的doc包含html

我已经尝试将分析器指定为index_analyzer,正如人们所期望的那样,以及其他几个绝望的search_analyzer和analyzer。 Non似乎对索引或检索的文档有任何影响。

根据HTML_Strip分析字段测试文档索引:

请求:带有html内容的示例POST文档

POST /html_poc_v2/html_poc_type/02
{
  "description": "Description <p>Some d&eacute;j&agrave; vu <a href=\"http://somedomain.com>\">website</a>",
  "title": "Title <p>Some d&eacute;j&agrave; vu <a href=\"http://somedomain.com>\">website</a>",
  "body": "Body <p>Some d&eacute;j&agrave; vu <a href=\"http://somedomain.com>\">website</a>"
}

预期:已通过html分析器解析的索引数据。 实际:数据使用html索引

RESPONSE

{
   "_index": "html_poc_v2",   "_type": "html_poc_type",   "_id": "02", ...
   "_source": {
      "description": "Description <p>Some d&eacute;j&agrave; vu <a href=\"http://somedomain.com>\">website</a>",
      "title": "Title <p>Some d&eacute;j&agrave; vu <a href=\"http://somedomain.com>\">website</a>",
      "body": "Body <p>Some d&eacute;j&agrave; vu <a href=\"http://somedomain.com>\">website</a>"
   }
}

设置和文档制图

PUT /html_poc_v2
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_html_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "char_filter": [
            "html_strip"
          ]
        }
      }
    },
    "mappings": {
      "html_poc_type": {
        "properties": {
          "body": {
            "type": "string",
            "analyzer": "my_html_analyzer"
          },
          "description": {
            "type": "string",
            "analyzer": "my_html_analyzer"
          },
          "title": {
            "type": "string",
            "search_analyser": "my_html_analyzer"
          },
          "urlTitle": {
            "type": "string"
          }
        }
      }
    }
  }
}

测试证明Custom Analyzer完美运行:

请求

GET /html_poc_v2/_analyze?analyzer=my_html_analyzer
{<p>Some d&eacute;j&agrave; vu <a href="http://somedomain.com>">website</a>}

响应

{
   "tokens": [
      {
         "token": "Some",… "position": 1
      },
      {
         "token": "déjà",… "position": 2
      },
      {
         "token": "vu",…  "position": 3
      },
      {
         "token": "website",… "position": 4
      }
   ]
}

引擎盖下

通过内联脚本深入了解我的html分析器必须被跳过

请求

GET /html_poc_v2/html_poc_type/_search?pretty=true
{
  "query" : {
    "match_all" : { }
  },
  "script_fields": {
    "terms" : {
        "script": "doc[field].values",
        "params": {
            "field": "title"
        }
    }
  }
}

RESPONSE

{ …
   "hits": { ..
      "hits": [
         {
            "_index": "html_poc_v2",
            "_type": "html_poc_type",
            …
            "fields": {
               "terms": [
                  [
                     "a",
                     "agrave",
                     "d",
                     "eacute",
                     "href",
                     "http",
                     "j",
                     "p",
                     "some",
                     "somedomain.com",
                     "title",
                     "vu",
                     "website"
                  ]
               ]
            }
         }
      ]
   }
}

此处与此问题类似:Why HTML tag is searchable even if it was filtered in elastic search

我也读过这个神奇的文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-htmlstrip-charfilter.html

ES版本:1.7.2

请帮助。

1 个答案:

答案 0 :(得分:5)

你混淆了&#34; _source &#34;响应中的字段返回正在分析和索引的内容。 看起来您的期望是响应中的_source字段返回分析的文档。这是不正确的。

来自documentation;

  

_source字段包含原始的JSON文档正文   在索引时间通过。 _source字段本身没有索引(和   因此是不可搜索的),但它被存储以便可以返回   执行获取请求时,如获取或搜索。

理想情况下,在上述情况下,您希望格式化源数据以用于演示目的,它应该在客户端完成。

然而,据说上述用例实现它的一种方法是使用script fieldskeyword-tokenizer,如下所示:

PUT test
{
   "settings": {
      "analysis": {
         "analyzer": {
            "my_html_analyzer": {
               "type": "custom",
               "tokenizer": "standard",
               "char_filter": [
                  "html_strip"
               ]
            },
            "parsed_analyzer": {
               "type": "custom",
               "tokenizer": "keyword",
               "char_filter": [
                  "html_strip"
               ]
            }
         }
      }
   },
   "mappings": {
      "test": {
         "properties": {
            "body": {
               "type": "string",
               "analyzer": "my_html_analyzer",
               "fields": {
                  "parsed": {
                     "type": "string",
                     "analyzer": "parsed_analyzer"
                  }
               }
            }
         }
      }
   }
}


PUT test/test/1 
{
    "body" : "Title <p> Some d&eacute;j&agrave; vu <a href='http://somedomain.com'> website </a> <span> this is inline </span></p> "
}

GET test/_search
{
  "query" : {
    "match_all" : { }
  },
  "script_fields": {
    "terms" : {
        "script": "doc[field].values",
        "params": {
            "field": "body.parsed"
        }
    }
  }
}

结果:

{
   "_index": "test",
   "_type": "test",
   "_id": "1",
   "_score": 1,
   "fields": {
        "terms": [
            "Title \n Some déjà vu  website   this is inline \n "
           ]
        }
   }

注意我认为以上是一个坏主意,因为剥离html标签可以在客户端轻松实现,并且您可以更多地控制格式化,而不是依赖于此类工作。更重要的是,它可能在客户端执行它。