天天看點

elasticsearch用于html去标簽化搜尋

場景

elasticsearch用于html去标簽化搜尋:即在Index的時候忽略html tag,同時又存儲了完整的html,在使用的時候可以正常讀出來。

示例

假設我們給content字段自定義analyzer ,分别是:html_text_analyzer,html_keyword_analyzer

定義兩種過濾html标記後,自動生成的沒有html标簽的index

PUT my_index
{
  "settings": { 
    "analysis": {
      "analyzer": {
        "html_text_analyzer": {
          "tokenizer": "standard",
          "char_filter": ["html_char_filter"]
        },
        "html_keyword_analyzer": {
          "tokenizer": "keyword",
          "filter":["trim"],
          "char_filter": ["html_char_filter"]
        }
      },
      "char_filter": {
        "html_char_filter": {
          "type": "html_strip"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "content":{
        "type": "text",
        "fields": {
          "html_text":{
            "search_analyzer": "simple",
            "analyzer":"html_text_analyzer",
            "type":"text"
          },
          "html_keyword":{
            "analyzer":"html_keyword_analyzer",
            "type":"text"
          }
        }
      }
    }
  }}      

mappings 設定字段子類型,一個字段建立三種index (預設:analyzer,html_text,html_keyword),友善比較

檢視剛才設定的mappings

GET my_index/_mapping

下面我們測試一下html_text_analyzer

//測試

POST my_index/_analyze
{
  "analyzer": "html_text_analyzer",
  "text": "<p>I'm so <b>happy</b>!</p>"
}

// 傳回結果

{
  "tokens" : [
    {
      "token" : "I'm",
      "start_offset" : 3,
      "end_offset" : 11,
      "type" : "<ALPHANUM>",
      "position" : 0
    },
    {
      "token" : "so",
      "start_offset" : 12,
      "end_offset" : 14,
      "type" : "<ALPHANUM>",
      "position" : 1
    },
    {
      "token" : "happy",
      "start_offset" : 18,
      "end_offset" : 27,
      "type" : "<ALPHANUM>",
      "position" : 2
    }
  ]
}      

下面我們測試一下html_keyword_analyzer

POST my_index/_analyze
{
  "analyzer": "html_keyword_analyzer",
  "text": "<p>I'm so <b>happy</b>!</p>"
}

// 傳回結果  去除html标記,全文被索引為一個keyword
{
  "tokens" : [
    {
      "token" : "I'm so happy!",
      "start_offset" : 0,
      "end_offset" : 32,
      "type" : "word",
      "position" : 0
    }
  ]
}      

錄入資料測試比較一下:

//錄入資料 帶span标記
POST my_index/_doc
{
  "content":"<span>I'm so <b>happy</b>!</span>"
}


//查詢my_index結果,原始的text類型使用預設analyzer,查詢span,能傳回結果是因為span也被索引了

POST my_index/_search
{
  "query": {
    "match": {
      "content": "span"
    }
   }
}
  
  
//查詢使用html_text_analyzer建立的索引中的span,無傳回結果結果,說明html标記沒有被索引

POST my_index/_search
{
  "query": {
    "match": {
      "content.html_text": "span"
    }
   }
}
  
  
//查詢使用html_text_analyzer建立的索引中的happy,能傳回結果,html中text被正常索引

POST my_index/_search
{
  "query": {
    "match": {
      "content.html_text": "happy"
    }
   }
}
  
// 查詢使用html_keyword_analyzer建立的索引中的happy,無傳回結果,因為這裡要用keyword的查詢文法

POST my_index/_search
{
  "query": {
    "match": {
      "content.html_keyword": "happy"
    }
   }
}