タグ付けハンドラー

タグ付けリクエストハンドラー (別名 "SolrTextTagger") は、「テキストタグ付け器」です。

名前のようなフィールドを持つ辞書 (Solr インデックス) が与えられた場合、このリクエストハンドラーにテキストを投稿すると、オフセットとその他の必要なドキュメントメタデータと共に、それらの名前の出現箇所がすべて返されます。これは、固有表現認識 (NER) に使用されます。

タグ付け器は自然言語処理 (NLP) を行いません (Lucene テキスト分析以外)。そのため、「ナイーブタグ付け器」と見なされますが、そのままでも非常に役立ち、より完全な NER または ERD (エンティティ認識と曖昧性解消) システムを構築できます。 SolrTextTagger は、クエリ理解や大きなドキュメントのクエリにも使用できます。

使用方法については、以下のチュートリアルを参照してください。

タグ付けリクエストハンドラーは、まだシャード化されたインデックスを**サポートしていません**。 SolrCloud モードで実行されているクラスタで使用できますが、タグ辞書を格納するコレクションは、単一シャードのコレクションでなければなりません。この制限にもかかわらず、数千万から数億の名前 (ドキュメント) をサポートできます。最大値は、ほとんどメモリによってのみ制限されます。

タグ付けの設定

タグ付けを設定するには、Solr スキーマに 2 つのフィールドが必要です。

  • 一意のキーフィールド (スキーマで一意のキーを定義する方法については、一意のキーを参照)。推奨フィールド設定: docValues=true を設定します。

  • タグフィールド。これは TextField でなければならず、インデックスチェーンの最後 (クエリチェーンではなく) に ConcatenateGraphFilterFactory があります。そのフィルターで preservePositionIncrements=false を設定します。推奨フィールド設定: omitNorms=trueomitTermFreqAndPositions=true、そして*おそらく* postings 形式を指定します - パフォーマンスのヒントを参照してください。

テキストフィールドのインデックス解析チェーンは、最後にConcatenateGraphFilterFactory が必要であることを除けば、一致の設定に合わせて任意のトークナイザーとフィルターを使用できます。たとえば、複数語の同義語を使用したり、WordDelimiterGraphFilterFactory を使用したりできます。ただし、FlattenGraphFilterFactoryConcatenateGraphFilterFactory と干渉するため、使用しないでください。位置ギャップ(例:ストップワード)は無視されます。ギャップが重要であることは(まだ)サポートされていません。

一方、テキストフィールドのクエリ解析チェーンは、より制限されています。同じ位置にトークンがあってはならないため、同義語展開はありません。代わりにインデックス時に実行してください。ストップワード(または位置ギャップを導入するその他のフィルター)はサポートされています。実行時に、タグ付け器はそれをタグの区切りとして扱うか、無視するように設定できます。

solrconfig.xml には、solr.TagRequestHandler を定義する必要があります。これは、検索ハンドラーと同様に、defaultsinvariants、および appends セクションをサポートします。

設定例については、以下のチュートリアルを参照してください。

タグ付け器のパラメーター

タグ付け器の実行は、リクエストパラメーターで完全に設定可能です。 field のみ必須です。

field

必須

デフォルト:なし

辞書として機能するタグフィールド。これは必須です。おそらくリクエストハンドラーで指定することになります。

fq

オプション

デフォルト:なし

タグ付けに使用される辞書を制限するために、いくつかのフィルタークエリを指定できます。このパラメーターは、solr.SearchHandler で使用されるものと同じです。

rows

オプション

デフォルト:10000

返されるドキュメントの最大数。このパラメーターは、solr.SearchHandler で使用されるものと同じです。

fl

オプション

デフォルト:なし

返されるフィールドをリストするためのSolrの標準パラメーター。このパラメーターは、solr.SearchHandler で使用されるものと同じです。

overlaps

オプション

デフォルト:NO_SUB

重複するタグのセットの中で、どのタグを保持し、どのタグを削除するかを決定するアルゴリズムを選択します。オプションは次のとおりです。

  • ALL:すべてのタグを出力します。

  • NO_SUB:別のタグ内に完全に含まれるタグ(つまり、サブタグなし)は出力しません。

  • LONGEST_DOMINANT_RIGHT:重複するタグのクラスターが与えられた場合、最も長いタグ(文字長による)を出力します。同じ長さの場合は、最も右側のタグを選択します。このタグと重複するタグをすべて削除してから、アルゴリズムを繰り返して、クラスター内で出力できる他のタグを検出します。

matchText

オプション

デフォルト:false

true の場合、タグのレスポンスで一致したテキストを返します。これにより、タグ付け器はタグ付け前に入力を完全にバッファリングします。

tagsLimit

オプション

デフォルト:1000

レスポンスで返されるタグの最大数。このポイントに達すると、タグ付けは事実上停止します。

skipAltTokens

オプション

デフォルト:false

true の場合、通常は行うべきではない、アナライザーでクエリ時に同義語展開を有効にした場合などに発生する可能性のあるエラーを抑制します。このようなトークンを回避できないことがわかっている場合を除き、デフォルトの false のままにしてください。

ignoreStopwords

オプション

デフォルト:false

ストップワード(または255文字を超える単語など、位置をスキップさせる条件)を存在しないかのように無視させるブール値フラグ。そうでない場合、インデックス付きテキスト解析設定に StopWordFilter が定義されていないという前提で、タグ付けの区切りとして扱われます。デフォルトでは、インデックス付き解析チェーンに StopWordFilter が存在するかどうかがチェックされ、見つかった場合は、指定されていない場合、ignoreStopWords は true になります。おそらく StopWordFilter を設定するべきではなく、このパラメーターを設定する必要もないでしょう。

xmlOffsetAdjust

オプション

デフォルト:false

true の場合、入力はXMLであり、返されたタグのオフセットは、クライアントがタグのオフセットペアに開始要素と終了要素を挿入できるように、必要に応じて調整する必要があることを示します。それができない場合は、タグは省略されます。このオプションを使用する場合は、スキーマで HTMLStripCharFilterFactory を設定することが想定されています。これにより、タグ付け器はタグ付け前に入力を完全にバッファリングします。

echoParamswtindent など、レスポンス形式を制御するためのSolrのパラメーターもサポートされています。

Geonamesを使ったチュートリアル

これは、一般的な Geonames データセットを使用してテキストタグ付け器を設定および使用する方法を示すチュートリアルです。チュートリアル以上の内容で、上記で説明されていない情報を含むハウツーです。

Solrコレクションの作成と設定

"geonames"という名前のSolrコレクションを作成します。チュートリアルでは、デフォルトの「データ駆動型」設定を想定します。これは、実験や迅速な開始には適していますが、本番環境や最適化には適していません。

bin/solr create -c geonames

タグ付け器の設定

最初にスキーマを設定する必要があります。使用している「データ駆動型」モードでは、この手順を最小限に抑えることができます。フィールドタイプ、2つのフィールド、およびコピーフィールドを宣言するだけで済みます。

最初に重要なのは、「タグ」フィールドタイプを定義することです。テキスト分析を設定する方法はたくさんあり、ここではそれらの選択肢については詳しく説明しません。ただし、重要なのは、インデックスアナライザーチェーンの最後にある ConcatenateGraphFilterFactory です。パフォーマンスにとってもう一つ重要なのは、postingsFormat=FST50 で、コンパクトなFSTベースのインメモリデータ構造が作成されることです。これは、テキストタグ付け器にとって特に有益です。

スキーマ設定

curl -X POST -H 'Content-type:application/json'  https://127.0.0.1:8983/solr/geonames/schema -d '{
  "add-field-type":{
    "name":"tag",
    "class":"solr.TextField",
    "postingsFormat":"FST50",
    "omitNorms":true,
    "omitTermFreqAndPositions":true,
    "indexAnalyzer":{
      "tokenizer":{
         "class":"solr.StandardTokenizerFactory" },
      "filters":[
        {"class":"solr.EnglishPossessiveFilterFactory"},
        {"class":"solr.ASCIIFoldingFilterFactory"},
        {"class":"solr.LowerCaseFilterFactory"},
        {"class":"solr.ConcatenateGraphFilterFactory", "preservePositionIncrements":false }
      ]},
    "queryAnalyzer":{
      "tokenizer":{
         "class":"solr.StandardTokenizerFactory" },
      "filters":[
        {"class":"solr.EnglishPossessiveFilterFactory"},
        {"class":"solr.ASCIIFoldingFilterFactory"},
        {"class":"solr.LowerCaseFilterFactory"}
      ]}
    },

  "add-field":{"name":"name", "type":"text_general"},

  "add-field":{"name":"name_tag", "type":"tag", "stored":false },

  "add-copy-field":{"source":"name", "dest":["name_tag"]}
}'

カスタムSolrリクエストハンドラーの設定

curl -X POST -H 'Content-type:application/json' https://127.0.0.1:8983/solr/geonames/config -d '{
  "add-requesthandler" : {
    "name": "/tag",
    "class":"solr.TaggerRequestHandler",
    "defaults":{"field":"name_tag"}
  }
}'

サンプルデータのロード

CSV形式のGeonames.orgデータを使用します。Solrは、さまざまな形式のデータのロードに非常に柔軟に対応しています。この cities1000.zip は、約7MBのファイルで、展開すると約22.2MBのcities1000.txtファイルになり、人口が少なくとも1000人の世界の都市が1行ずつ、約145,000行含まれています。

bin/solr postの使用

bin/solr post -c geonames -type text/csv \
  -params 'optimize=true&maxSegments=1&separator=%09&encapsulator=%00&fieldnames=id,name,,alternative_names,latitude,longitude,,,countrycode,,,,,,population,elevation,,timezone,lastupdate' \
  /tmp/cities1000.txt

またはcurlの使用

curl -X POST --data-binary @/path/to/cities1000.txt -H 'Content-type:application/csv' \
  'https://127.0.0.1:8983/solr/geonames/update?commit=true&optimize=true&maxSegments=1&separator=%09&encapsulator=%00&fieldnames=id,name,,alternative_names,latitude,longitude,,,countrycode,,,,,,population,elevation,,timezone,lastupdate'

これには約35秒かかる場合があります。環境によって異なります。スキーマを本当に必要なものだけにするように調整すれば(テキスト検索が必要ない場合は調整しない)、はるかに高速になります。

このコマンドでは、optimize=true&maxSegments=1 を指定して、タグ付けを高速化する状態にインデックスを配置しました。 encapsulator=%00 は、デフォルトの二重引用符を無効にするためのちょっとしたハックです。

タグ付けの時間!

これは、小さなテキストをタグ付けする簡単な例です。その他のオプションについては、前のドキュメントを参照してください。

curl -X POST \
  'https://127.0.0.1:8983/solr/geonames/tag?overlaps=NO_SUB&tagsLimit=5000&fl=id,name,countrycode&wt=json&indent=on' \
  -H 'Content-Type:text/plain' -d 'Hello New York City'

レスポンスは次のようになります(QTimeは異なる場合があります)

{
  "responseHeader":{
    "status":0,
    "QTime":1},
  "tagsCount":1,
  "tags":[{
      "startOffset":6,
      "endOffset":19,
      "ids":["5128581"]}],
  "response":{"numFound":1,"start":0,"docs":[
      {
        "id":"5128581",
        "name":["New York City"],
        "countrycode":["US"]}]
  }}

タグ付け器のパフォーマンスのヒント

  • 上記の推奨設定フィールド設定に従ってください。さらに、タグ付け器のパフォーマンスを最大限に高めるには、postingsFormat=FST50 を設定します。ただし、デフォルト以外の postings format は下位互換性を保証していないため、Solrをアップグレードすると、古いインデックスの読み込みに失敗して、起動時に厄介な例外が発生する可能性があります。タグ付けされる入力テキストが小さい場合(たとえば、クエリまたはツイートをタグ付けする場合)、postings format の選択はそれほど重要ではありません。

  • 辞書をロードした後、1つのLuceneセグメント、または少なくともできるだけ少ないセグメントに「最適化」します。

  • 大量のドキュメントをバルクタグ付けする場合、いくつかの戦略があります。これらは相互に排他的ではありません。

    • バッチ処理します。タグ付け器はバッチ処理を直接サポートしていませんが、ハックとして、辞書にない「ZZYYXXAABBCC」のような無意味な単語で連結されたドキュメントの束を送信できます。これらの文字オフセットを追跡して、結果から減算する必要があります。

    • タグ付けのレイテンシをさらに削減するには、EmbeddedSolrServer を使用してSolrを埋め込むことを検討してください。 EmbeddedSolrNoSerializeTest を参照してください。

    • 複数のスレッドを使用します。おそらく、Solrで使用できるCPUコアの数と同じくらいです。