13

私のスキーマ:

<fieldType name="text" class="solr.TextField" positionIncrementGap="100">
  <analyzer>
    <tokenizer class="solr.WhitespaceTokenizerFactory"/>
    <filter class="solr.StopFilterFactory"
            ignoreCase="true"
            words="stopwords.txt"
            enablePositionIncrements="true"
            />
    <filter class="solr.WordDelimiterFilterFactory"
            generateWordParts="1" generateNumberParts="1"
            catenateWords="1" catenateNumbers="1" catenateAll="0"
            splitOnCaseChange="1" splitOnNumerics="0"/>
    <filter class="solr.LowerCaseFilterFactory"/>
    <filter class="solr.SnowballPorterFilterFactory" language="English"
            protected="protwords.txt"/>
  </analyzer>
</fieldType>

やりたい組み合わせ:

「ウォルマート」、「ウォルマート」、「ウォルマート」、「ウォルマート」、「ウォルマート」

これらの文字列のいずれかが与えられた場合、もう一方の文字列を見つけたいと思います。

したがって、以下に示すように 25 の組み合わせがあります。

(最初の列は検索用の入力テキストを示し、2 番目の列は予想される一致を示します)

(Walmart,Walmart)
(Walmart,WalMart)
(Walmart,Wal Mart)
(Walmart,Wal-Mart)
(Walmart,Wal-mart)
(WalMart,Walmart)
(WalMart,WalMart)
(WalMart,Wal Mart)
(WalMart,Wal-Mart)
(WalMart,Wal-mart)
(Wal Mart,Walmart)
(Wal Mart,WalMart)
(Wal Mart,Wal Mart)
(Wal Mart,Wal-Mart)
(Wal Mart,Wal-mart)
(Wal-Mart,Walmart)
(Wal-Mart,WalMart)
(Wal-Mart,Wal Mart)
(Wal-Mart,Wal-Mart)
(Wal-Mart,Wal-mart)
(Wal-mart,Walmart)
(Wal-mart,WalMart)
(Wal-mart,Wal Mart)
(Wal-mart,Wal-Mart)
(Wal-mart,Wal-mart)

私のスキーマの現在の制限:

1. "Wal-Mart" -> "Walmart",
2. "Wal Mart" -> "Walmart",
3. "Walmart"  -> "Wal Mart",
4. "Wal-mart" -> "Walmart",
5. "WalMart"  -> "Walmart"

アナライザーのスクリーンショット:

初期スキーマを使用したアナライザーのスクリーンショット

これらの制限を解決するために、さまざまなフィルターの組み合わせを試しましたが、Solr - 大文字と小文字を区別しない検索が機能しないソリューションにつまずきました。

私が持っている制限の 1 つを克服しているように見えますが (#5 ウォルマート -> ウォルマートを参照)、以前の制限よりも全体的に悪いです。現在、次のような場合には機能しません。

(Wal Mart,WalMart), 
(Wal-Mart,WalMart), 
(Wal-mart,WalMart), 
(WalMart,Wal Mart)
besides cases 1 to 4 as mentioned above

スキーマ変更後のアナライザー: ここに画像の説明を入力

質問:

  1. 「WalMart」が「Walmart」と初期スキーマと一致しないのはなぜですか? walSolr アナライザーは、インデックス時間中martに3 つのトークンを生成したことを明確に示していますwalmart。クエリ時間中: 1 つのトークンが生成されました: (トークンが 1 つしか生成されない理由は明らかではありませんが) 、クエリ トークンとインデックス トークンの両方に含まれるトークンがwalmart一致しない理由がわかりません。walmart

  2. ここで言及した問題は、1 つのユース ケースにすぎません。次のような少し複雑なものがあります。

    アポストロフィー付きの単語: 「マクドナルド」、「マクドナルド」、「マクドナルド」、「マクドナルド」、「マクドナルド」、「マクドナルド」

    句読点が異なる単語: 「マクドナルド エンジニアリング カンパニー」

一般に、この種の要件でスキーマをモデル化するための最良の方法は何ですか? Nグラム?異なるフィールド (異なる形式) で同じデータにインデックスを付け、copyField ディレクティブ ( https://wiki.apache.org/solr/SchemaXml#Indexing_same_data_in_multiple_fields ) を使用しますか? これのパフォーマンスへの影響は何ですか?

編集: 私の Solr スキーマのデフォルトの演算子は AND です。ORに変更できません。

4

4 に答える 4

5

ハイフンでつながれた単語を特別なケースと見なし、このトークンの 3 つのバージョンを作成するためにインデックス時に使用されるカスタム アナライザーを作成しました。これらのシノニムはそれぞれ、Lucene in Action ブックの例から最初に採用されたカスタム SynonymFilter を使用して書き出されました。SynonymFilter は、空白のトークナイザーと小文字のトークナイザーの間にありました。

検索時には、3 つのバージョンのいずれかがインデックス内のシノニムの 1 つと一致します。

于 2015-04-22T00:58:51.027 に答える
4

「WalMart」が「Walmart」と最初のスキーマと一致しないのはなぜですか?

mmDisMax/eDismax ハンドラーのパラメーターを高すぎる値で定義したためです。私はそれで遊んだことがあります。mm 値を 100% に定義すると、一致しなくなります。しかし、なぜ?

クエリ時間とインデックス時間に同じアナライザーを使用しているためです。検索用語「WalMart」は 3 つのトークン (単語) に分かれています。つまり、これらは「wal」、「mart」、および「walmart」です。<str name="mm">100%</str>Solr は、 *に向かって数えるとき、各単語を個別に扱うようになりました。

ところで、私はあなたの問題を再現しましたが、Walmartのインデックス作成時に問題が発生しますが、 WalMartでクエリを実行します。逆に実行すると、正常に動作します。

を使用してこれをオーバーライドできます。LocalParamsクエリを次のように言い換えることができます{!mm=1}WalMart

[ ... ] "Mc Donald's" [ 一致する ] 句読点の異なる単語: "Mc-Donald Engineering Company, Inc." のような、もう少し複雑なものがあります。

ここでも、mmパラメーターをいじってみると役立ちます。

一般に、この種の要件でスキーマをモデル化するための最良の方法は何ですか?

ここで私は Sujit Pal に同意しますSynonymFilter。なんで?他のフィルターやトークナイザーとは動作が異なるためです。索引付けされた単語のオフセットの代わりにトークンを作成します。

その場で何?クエリのトークン数は増えません。また、バック ハイフネーション (空白で区切られた 2 つの単語を結合すること) を実行できます。

しかし、適切な synonyms.txt がなく、最新の状態に保つことができません。

拡張またはコピーする場合SynonymFilter、静的マッピングは無視されます。単語をマップするコードを削除できます。オフセット処理が必要なだけです。

更新も試すことができると思いますがPatternCaptureGroupTokenFilter、正規表現で会社名に取り組むことは、すぐに限界に直面する可能性があります。これについては後で調べます。


* これはsolrconfig.xmlで見つけることができます。<requestHandler ... />

于 2015-05-11T13:45:11.673 に答える