web-dev-qa-db-ja.com

Elasticsearch:html_stripフィルターが機能しないドキュメントのインデックスを作成する前にHTMLタグを削除します

Givenカスタムアナライザーでhtmlストリップ文字フィルターを指定しました

WhenHTMLコンテンツでドキュメントにインデックスを付ける

次にHTMLがインデックス付きコンテンツから削除されることを期待しています

Andインデックスから返されたドキュメントを取得すると、hmtlが含まれていません。

[〜#〜] actual [〜#〜]:インデックスに登録されたドキュメントにhtmlが含まれていました取得されたドキュメントにhtmlが含まれていました

私は、アナライザーをindex_analyzerとして指定しようとしましたが、必死のsearch_analyzerとアナライザーから他のいくつかを指定しました。 Nonは、インデックス作成または取得するドキュメントに影響を与えないようです。

HTML_Strip分析フィールドに対するドキュメントインデックスのテスト:

リクエスト:例POST HTMLコンテンツを含むドキュメント

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

Expected:htmlアナライザーを介して解析されたインデックス付きデータ。 実際:データはhtmlでインデックス付けされます

[〜#〜]応答[〜#〜]

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

カスタムアナライザーが完全に機能することを証明するためのテスト:

[〜#〜]リクエスト[〜#〜]

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

[〜#〜]応答[〜#〜]

{ …
   "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"
                  ]
               ]
            }
         }
      ]
   }
}

ここでのこの質問と同様: エラスティック検索でフィルタリングされた場合でもHTMLタグが検索可能である理由

私もこの素晴らしいドキュメントを読みました: https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-htmlstrip-charfilter.html

ESバージョン:1.7.2

助けてください。

18
DaddyMoe

応答の「_ source」フィールドを混乱させて、分析およびインデックス付けされているものを返します。応答の_sourceフィールドが分​​析されたドキュメントを返すことを期待しているようです。これは正しくありません。

ドキュメント から;

_sourceフィールドには、インデックス作成時に渡された元のJSONドキュメント本文が含まれます。 _sourceフィールド自体はインデックス付けされていません(したがって検索できません)が、getやsearchなどのフェッチ要求を実行するときに返されるように格納されています。

理想的には、プレゼンテーションの目的でソースデータをフォーマットする上記の場合は、クライアント側で行う必要があります。

ただし、上記のユースケースでそれを実現する1つの方法は、次のように スクリプトフィールド および キーワードトークンライザー を使用することです。

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タグの削除はクライアント側で簡単に実行でき、このような回避策に依存するよりもフォーマットに関してはるかに多くの制御ができるため、上記は悪い考えだと思います。さらに重要なのは、クライアント側でそれを実行するパフォーマンスが高いことです。

5
keety