ご利用にはKandaSearchへの
ユーザー登録(無料)が必要です
最新バージョン: 2.4.0
開発者: RONDHUIT
ダウンロード数: 49
最終更新日: 2023-10-31
Copyright: RONDHUIT Co.,LTD
最新バージョン: 2.4.0
開発者: RONDHUIT
ダウンロード数: 49
最終更新日: 2023-10-31
Copyright: RONDHUIT Co.,LTD
ロンウイットが開発したApache Solrのプラグインです。日本語の検索機能を強化しています。
前処理やクエリ処理で動作するロンウイットの日本語処理プラグインでは、
を通して、日本語独特の表記揺れを吸収し、検索漏れの事故の未然防止や、ちょっとした工夫で効率や使い勝手を向上させながら、日本語の検索機能を強化します。
Normalizerクラスを使用したオフセット補正機能対応のCharFilterです。Normalizerとはテキストのソートや検索が容易になるように Unicode テキストをそれと等価な合成形式または分解形式に変換する機能です。
△は半角スペース
変換前 | 変換後 |
---|---|
あか”る | あがる |
あ△か”△る | あ△が△る |
A:BC | ÄBC |
A:△B△C | Ä△B△C |
パラメータ | 説明 |
---|---|
form | NFC(Normalize Function Composite) NFD(Normalize Function Decomposite) NFKC(Normalization Form Compatibility Composition) NFKD(Normalization Form Compatibility Decomposition) |
maxBlockChars | 一回で処理可能な最大文字数 |
schema.xml/managed-schemaの設定例(正規分解とそれに続く正規合成を実行します):
<fieldType name="text_ja" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<charFilter class="com.rondhuit.solr.analysis.JavaNormalizerCharFilterFactory" form="NFC" maxBlockChars="8192"/>
<tokenizer class="solr.JapaneseTokenizerFactory"/>
</analyzer>
</fieldType>
正規化された文字を含む単語のハイライトはずれる可能性があります(制限事項)。正規化された文字を含まない単語のハイライトはずれません。正規化された文字を含む単語をハイライトする可能性があるときは、MappingCharFilter の利用をご検討ください。
“四十七”などの漢数字を”47″という算用数字(アラビア数字)に正規化します。これにより、漢数字と算用数字どちらが使われている文書でも、漢数字または算用数字を使って検索できるようになります。オフセットも正しく計算するため、ハイライトずれも起きません。
参考までに JapaneseNumberFilter と出力が異なる場合、それも記載しておきます。JapaneseNumberFilter はトークンフィルターのため、JapaneseTokenizer を前段に使うことが条件となっています。
変換前 | 変換後 | JapaneseNumberFilterで出力が異なるもの |
---|---|---|
四七 | 47 | |
四十七 | 47 | |
四百七 | 407 | |
四〇七 | 407 | |
四千十七 | 4017 | |
一億 | 100000000 | |
1億 | 100000000 | |
一千億 | 100000000000 | |
壱億弐千参百四拾萬 | 12340000 | 壱, 億, 弐, 1000, 参, 104, 拾, 萬 |
schema.xml/managed-schemaの設定例:
<fieldType name="ja_number" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ja.txt"/>
<charFilter class="com.rondhuit.solr.analysis.KanjiNumberCharFilterFactory"/>
<tokenizer class="solr.JapaneseTokenizerFactory"/>
</analyzer>
</fieldType>
JapaneseKatakanaStemFilterのCharFilterバージョンです。CharFilterなので、N-gramにもカタカナ語末尾の長音記号の表記揺れに対応できます。また、オフセット補正機能付きなので、ハイライト表示もずれがなく行うことが可能です。
変換前 | 変換後 |
---|---|
サーバー | サーバ |
コンピューター | コンピュータ |
サーファー | サーファ |
schema.xml/managed-schemaの設定例:
<fieldType name="text_cjk" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ja.txt"/>
<charFilter class="com.rondhuit.solr.analysis.KatakanaStemCharFilterFactory"/>
<tokenizer class="solr.JapaneseTokenizerFactory"/>
</analyzer>
</fieldType>
外来語に使われる中黒(全角 U+30FB, 半角 U+FF65)の有無を正規化し、相互にヒットするようにします。 オフセット補正にも対応するので、ハイライトずれは起きません。
変換前 | 変換後 |
---|---|
オープンソース・ソフトウェア | オープンソースソフトウェア |
ザ・ビートルズ | ザビートルズ |
schema.xml/managed-schemaの設定例:
<fieldType name="gairaigo" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ja.txt"/>
<charFilter class="com.rondhuit.solr.analysis.NakaguroCharFilterFactory"/>
<tokenizer class="solr.JapaneseTokenizerFactory"/>
</analyzer>
</fieldType>
「時々」と「時時」など、漢字/ひらがな/カタカナ文字の繰り返し記号を使用するいわゆる 「踊り字」のサポート機能です。踊り字を含む単語を踊り字を含まない単語に正規化することで、踊り字を含む文書も含まない文書も、踊り字を含む単語/含まない単語どちらで検索してもヒットするようになります。
変換前 | 変換後 | 備考 | JapaneseIterationMarkCharFilterで出力が異なるもの |
---|---|---|---|
様々 | 様様 | ||
本日から大々々売り出し | 本日から大大大売り出し | 「々々」の直前が漢字1文字のため | 本日から大大々売り出し |
部分々々 | 部分部分 | 「々々」の直前が漢字2文字のため | |
つゝみ | つつみ | ||
いすゞ | いすず | ||
あ々 | あ々 | 「々」はひらがなには適用されない | ああ |
ツヽジ | ツツジ | ||
つゝゞ | つつづ | ||
1つゞゝ | 1つづつ |
schema.xml/managed-schemaの設定例:
<fieldType name="text_ja" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ja.txt"/>
<charFilter class="com.rondhuit.solr.analysis.OdorijiCharFilterFactory"/>
<tokenizer class="solr.JapaneseTokenizerFactory"/>
</analyzer>
</fieldType>
全角カタカナまたはひらがなのうしろの下表の文字を長音記号(U+30FC “KATAKANA-HIRAGANA PROLONGED SOUND MARK”)に正規化するCharFilterです。半角カタカナのうしろは関知しないので、必要ならMappingCharFilterなどで半角カタカナを全角カタカナに変換する必要があります。
文字コード | 文字名称 | 文字 |
---|---|---|
U+002D | HYPHEN-MINUS | - |
U+FF0D | FULLWIDTH HYPHEN-MINUS | - |
U+2010 | HYPHEN | ‐ |
U+2011 | NON-BREAKING HYPHEN | ‑ |
U+2012 | FIGURE DASH | ‒ |
U+2013 | EN DASH | – |
U+2014 | EM DASH | — |
U+2015 | HORIZONTAL BAR | ― |
U+207B | SUPERSCRIPT MINUS | ⁻ |
U+208B | SUBSCRIPT MINUS | ₋ |
schema.xml/managed-schemaの設定例:
<fieldType name="text_ja" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ja.txt"/>
<tokenizer class="solr.JapaneseTokenizerFactory"/>
</analyzer>
<analyzer type="query">
<charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ja.txt"/>
<charFilter class="com.rondhuit.solr.analysis.ProlongedSoundMarkCharFilterFactory"/>
<tokenizer class="solr.JapaneseTokenizerFactory"/>
</analyzer>
</fieldType>
和暦年を西暦年に正規化するCharFilterです。検索時に和暦と西暦を相互ヒットさせることが可能です。飛鳥時代(大化元年)から現代(令和)までをサポートします。 年数は半角算用数字でなければならないため、通常、KanjiNumberCharFilterと組み合わせて用います。 オフセットも正しく計算するため、ハイライトずれも起きません。
変換前 | 変換後 | |
---|---|---|
大化元年 大化1年 |
645年 | 元年でも1年でもOK |
明治30年 明治三十年 明治参拾年 |
1897年 | KanjiNumberCharFilterが必要 |
昭和64年 平成元年 |
1989年 | 昭和と平成が重なった年もOK |
schema.xml/managed-schemaの設定例:
<fieldType name="wareki" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ja.txt"/>
<charFilter class="com.rondhuit.solr.analysis.KanjiNumberCharFilterFactory"/>
<charFilter class="com.rondhuit.solr.analysis.WarekiCharFilterFactory"/>
<tokenizer class="solr.JapaneseTokenizerFactory"/>
</analyzer>
</fieldType>
文章中で一定以上連続するアルファベット、漢字やカタカナ文字、またはカタカナ+漢字ミックスは専門用語と見なしてトークンを抽出します。抽出された専門用語はファセット、クラスタリング、レコメンド、サジェスト(オートコンプリート)、もしかして検索などで活用できます。
以下のパラメータが指定できます。
パラメータ | デフォルト | 説明 |
---|---|---|
minAlphabetLen | 4 | 抽出するアルファベットの最小連続文字列数。 |
minKatakanaLen | 7 | 抽出するカタカナの最小連続文字列数。 |
minKanjiLen | 4 | 抽出する漢字の最小連続文字列数。 |
minMixLen | 4 | 抽出する漢字とカタカナ混合の最小連続文字列数。 |
allowMix | true | 漢字とカタカナの混合を抽出対象とみなすか否か。 |
トークナイズ前 | トークナイズ後 | 備考 |
---|---|---|
Solr大規模分散検索オープンソース | Solr / 大規模分散検索オープンソース | 専門用語が漢字+カタカナミックス (allowMix="true"に設定時) |
大規模分散検索Solrオープンソース | 大規模分散検索 / Solr / オープンソース | |
Information関東関西大学インフォメーション情報処理学科 | Information / 関東関西大学 / インフォメーション / 情報処理学科 | allowMix="false"に設定時 |
etc国立私立大学カタカナ関東関西大学インフォメーション | 国立私立大学 / 関東関西大学 / インフォメーション | 「etc」、「カタカナ」は脱落 (allowMix="false"に設定時) |
schema.xml/managed-schemaの設定例:
<fieldType name="text_buzz" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ja.txt"/>
<tokenizer class="com.rondhuit.solr.analysis.JaBuzzPhraseTokenizerFactory"
minAlphabetLen="4" minKatakanaLen="5" minKanjiLen="4" allowMix="false"/>
</analyzer>
</fieldType>
検索性能を考慮した、漢字のみ1-gramで処理するTokenizerです。1-gram フィールドを安易に使用すると、検索性能を大きく劣化させます。日本語環境で1文字検索をしたい場合、漢字1文字となることがほとんどですので、「1文字検索があり得るが、検索性能を落としたくない」という場合に便利です。
independentOnly=trueの場合(デフォルト)、漢字が2文字以上連続している場合除外されます。independentOnly=falseの場合、全ての漢字を対象とします。
トークナイズ前 | トークナイズ後 | 備考 |
---|---|---|
昨日は休みでした | 昨 / 日 / 休 | independentOnly=false、全ての漢字が1-gramで処理、漢字以外は脱落 |
昨日は休みでした | 休 | independentOnly=true、「昨日」は漢字2文字が連続しているため脱落 |
schema.xml/managed-schemaの設定例:
<fieldType name="text_1k" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="com.rondhuit.solr.analysis.Kanji1GramTokenizerFactory" independentOnly="false"/>
</analyzer>
</fieldType>
ルールベースの固有表現抽出を行うTokenizerで、FST(Finite State Transducer)上に作成された辞書に掲載されているキーワードだけをトークナイズします。
固有表現抽出とは、人名、地名、組織名などの固有名詞を、属性付きで自然言語の文書から抽出するタスクです。 固有名詞やキーワードを辞書に登録することで、辞書に記載した単語だけをコンテンツから抽出しファセット表示の軸などとして用いることができます。 固有表現抽出をSolrと組み合わせると、特にフィールドの少ない企業内検索に多大な威力を発揮します。 企業ドメインの専門用語や固有表現をあらかじめ抽出しておくことで、ユーザはその専門用語を使ってドキュメントの絞り込みができるようになります。
辞書に登録されている単語だけがコンテンツから抽出されます。
トークナイズ前 | トークナイズ後 |
---|---|
安倍首相は外遊先のフィリピンで「本当は消費税を上げたくない」と本音を漏らした。 | 安倍首相 / フィリピン / 消費税 |
schema.xml/managed-schemaの設定例:
<fieldType name="text_known" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="com.rondhuit.solr.analysis.KnownWordsTokenizerFactory"
words="javaclasses.txt" ignoreCase="false"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.KeywordTokenizerFactory"/>
</analyzer>
</fieldType>
known_org.txt (辞書)の設定例:
安倍首相
フィリピン
消費税
ReadingAttributeの読みをローマ字に変換してCharTermAttributeに入れます。ReadingAttributeが空の場合は、CharTermAttributeを可能な範囲でローマ字に変換します。
変換前 | 変換後 |
---|---|
東京 | tōkyō |
schema.xml/managed-schemaの設定例:
<!-- 漢字トークンの読みをローマ字に変換 -->
<fieldType name="text_ja_spell" class="solr.TextField">
<analyzer>
<tokenizer class="solr.JapaneseTokenizerFactory"/>
<filter class="com.rondhuit.solr.analysis.JaReadingInjectionFilterFactory"/>
</analyzer>
</fieldType>
トークン文字列の「タイプ」(ひらがな、カタカナ、漢字、アルファベット)を基準にフィルタリングします。 保持対象のタイプは以下の該当パラメータをtrueに指定してください。
変換前 | 変換後 | 保持対象のタイプ |
---|---|---|
トウキョウ | トウキョウ | keepKatakana |
東京 | keepKatakana | |
とうきょう | keepKatakana | |
tokyo | keepKatakana | |
東京 | 東京 | keepKanji |
とうきょう | とうきょう | keepHiragana |
tokyo | tokyo | keepAlphabet |
schema.xml/managed-schemaの設定例:
<fieldType name="katakana" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.JapaneseTokenizerFactory"/>
<filter class="com.rondhuit.solr.analysis.JaStringTypeFilterFactory" keepKatakana="true"/>
</analyzer>
</fieldType>
N-gram系トークナイザーで使えるGosenKatakanaStemFilterで、カタカナのトークンの末尾に長音(ー)があれば除去します。
schema.xml/managed-schemaの設定例:
<fieldType name="text_2g" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ja.txt"/>
<tokenizer class="solr.NGramTokenizerFactory" minGramSize="2" maxGramSize="2"/>
<filter class="com.rondhuit.solr.analysis.NGramKatakanaStemFilterFactory"/>
</analyzer>
</fieldType>
検索語サジェスチョン専用のTokenFilter。
検索語サジェスチョンでは日本語IMEでの入力途中・変換前の文字列に対して日本語形態素解析が行われるため、半端に分断されてしまったトークンを連結します。トークン連結後に、IME入力途中でもマッチする工夫を凝らした、ローマ字変換を行います。また、同じ読みの漢字対応として、ローマ字に加えて、異なる漢字として識別します。
schema.xml/managed-schemaの設定例:
<fieldType name="suggest_ja" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ja.txt"/>
<tokenizer class="solr.JapaneseTokenizerFactory"/>
<filter class="com.rondhuit.solr.analysis.JaSuggestFilterFactory" concatKanjiToken="false" matchExactKanji="true"/>
</analyzer>
</fieldType>
同一の文字列を持つトークンを除去するTokenFilter
JaBuzzPhraseTokenizerやKanji1GramTokenizer、KnownWordsTokenizerなどで、同じ文字列を持つトークンが複数個生成されてしまい、ランキングの都合からそれらを除去したい場合に利用します。
schema.xml/managed-schemaの設定例:
<fieldType name="suggest_ja" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ja.txt"/>
<tokenizer class="com.rondhuit.solr.analysis.JaBuzzPhraseTokenizerFactory" minAlphabetLen="4" minKatakanaLen="5" minKanjiLen="4"/>
<filter class="com.rondhuit.solr.analysis.UniqueTokenFilterFactory"/>
</analyzer>
</fieldType>
インデクシング時リクエストのすべてのドキュメントに対し、fieldParam 中の name で指定されたパラメータのフィールドに、value で指定されたパラメータの値を追加します。シングルコア環境でマルチテナントを実現するのに便利に使えます。検索時は CheckIndexSubsetComponent を組み合わせてご利用ください。
solrconfig.xmlの設定を以下のように行っておき、
<updateRequestProcessorChain name="addReqParams">
<processor class="com.rondhuit.solr.update.AddFieldsFromRequestParametersUpdateRequestProcessorFactory">
<lst name="fieldParam">
<str name="name">affrp.field</str>
<str name="value">affrp.value</str>
</lst>
<bool name="ignore">false</bool>
</processor>
<processor class="solr.RunUpdateProcessorFactory" />
<processor class="solr.LogUpdateProcessorFactory" />
</updateRequestProcessorChain>
インデクシング時は
?update.chain=addReqParams&affrp.field=_member&affrp.value=5508abc7
などと呼び出すと、 _member
フィールドに 5508abc7
が埋め込まれます。指定されたパラメータが見つからない場合、ignore の設定にしたがいます。ignore が false(デフォルト)のとき、例外を発行し、インデクシングプロセスが失敗します。ignore が true のとき、インデクシングを続行します。
fieldParam の部分は次のように複数指定できます。
<updateRequestProcessorChain name="addReqParams">
<processor class="com.rondhuit.solr.update.AddFieldsFromRequestParametersUpdateRequestProcessorFactory">
<lst name="fieldParam">
<str name="name">affrp.field1</str>
<str name="value">affrp.value1</str>
</lst>
<lst name="fieldParam">
<str name="name">affrp.field2</str>
<str name="value">affrp.value2</str>
</lst>
<bool name="ignore">false</bool>
</processor>
<processor class="solr.RunUpdateProcessorFactory" />
<processor class="solr.LogUpdateProcessorFactory" />
</updateRequestProcessorChain>
この場合、affrp.field1, affrp.value1, affrp.field2, affrp.value2 のどれか一つでもパラメータが見つからない場合、前述の ignore の設定にしたがった動作となります。
maxLength に達するまで StrField や TextField のフィールド値を保持し、maxLength に達した以降の値は切り捨てます。alternateField をサポートしていない Unified Highlighter 利用時に、alternateField の代用として使うと便利です。
Solr の FieldMutatingUpdateProcessorFactory を継承しているので、処理対象とするフィールドを fieldName
, typeName
, fieldRegex
, typeClass
で指定できるほか、 exclude
で処理対象外のフィールドを指定することができます。たとえば、以下のような設定をしておき
<updateRequestProcessorChain name="heads">
<processor class="com.rondhuit.solr.update.HeadsFieldValueUpdateProcessorFactory">
<str name="typeClass">solr.StrField</str>
<int name="maxLength">100</int>
</processor>
<processor class="solr.RunUpdateProcessorFactory" />
<processor class="solr.LogUpdateProcessorFactory" />
</updateRequestProcessorChain>
インデクシング時は
?update.chain=heads
と呼び出せば、全StrFieldのフィールドを対象に、フィールド値の長さが100に達した以降の値を切り捨てます。
srcで指定したフィールド名(カンマ区切りで複数指定可能)からdestのwordsで指定したファイルに一覧されているキーワードを抽出し、destのfieldsに指定したフィールドに出力します。destのfieldsのフィールドはmultiValuedでなければなりません。 destのfieldsとwordsはカンマ区切りで複数指定が可能ですが、指定数は同じにしなければなりません。また、指定順序は一致させなければなりません。fieldsのフィールド名指定には’’(アスタリスク)が使えます。その場合、 ‘’はsrcのフィールド名に置き換えられます。
下記の設定例で説明すると、textフィールドからknown-locations.txtに一覧されている地名が抽出されてtext_locationフィールドに出力され、known_persons.txtに一覧されている人名が抽出されてtext_personフィールドに出力されます。titleフィールドからも同様の抽出が行われ、地名と人名がそれぞれtitle_location、title_personフィールドに出力されます。
辞書にアルファベット文字がある場合、その辞書の表記の大文字小文字の区別はデフォルトで尊重されます。大文字小文字の区別を行いたくない場合は、下記設定例のように ignoreCase=true
を指定します。
src | dest person | dest location |
---|---|---|
こんにちは、佐藤さん。あら、こんにちは、鈴木さん。 | 佐藤、鈴木 | |
陽気な佐藤さんと東京都の田中さん | 佐藤、田中 | 東京都 |
solrconfig.xmlの設定:
<updateRequestProcessorChain name="known4">
<processor class="com.rondhuit.solr.update.KnownWordsExtractUpdateProcessorFactory">
<bool name="ignoreCase">true</bool>
<str name="src">text,title</str>
<lst name="dest">
<str name="fields">*_location,*_person</str>
<str name="words">known-locations.txt,known-persons.txt</str>
</lst>
</processor>
<processor class="solr.UniqFieldsUpdateProcessorFactory">
<str name="fieldName">plan_sm</str>
</processor>
<processor class="solr.RunUpdateProcessorFactory" />
<processor class="solr.LogUpdateProcessorFactory" />
</updateRequestProcessorChain>
srcで指定したフィールド値をfieldTypeで指定したフィールド型のインデックスAnalyzerで処理し、その結果文字列をdestで指定したフィールドに出力します。srcはmultiValuedでもよいです。インデックスAnalyzerで処理した際に、出力されるトークンは連結されて出力文字列となりますが、N番目のトークンの終了オフセットとN+1番目のトークンの開始オフセットが異なる場合、その間隙を埋めるべく差分の数のスペースが付加されます。
src | dest |
---|---|
ABC DEF GHIJKL | abc def ghijkl |
solrconfig.xmlの設定:
<updateRequestProcessorChain name="analyzerMV">
<processor class="com.rondhuit.solr.update.NormalizeFieldByAnalyzerUpdateProcessorFactory">
<str name="src">text_sm</str>
<str name="dest">suggest_sm</str>
<str name="fieldType">text_low</str>
</processor>
<processor class="solr.RunUpdateProcessorFactory" />
<processor class="solr.LogUpdateProcessorFactory" />
</updateRequestProcessorChain>
schema.xml/managed-schemaの設定:
<fieldType name="text_low" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
fieldで指定したフィールド値をacceptまたはdenyで指定した正規表現のパターンでマッチ判定を行い、当該ドキュメントを受け入れる(accept)か拒否する(deny)かを決めます。fieldはmultiValuedでもよいです。acceptを指定した場合、fieldのフィールド値がマッチしたら当該ドキュメントを受け入れます。denyを指定した場合、fieldのフィールド値がマッチしたら当該ドキュメントを拒否します。ドキュメントにfieldのフィールドが存在しない場合、「マッチしない」と解釈され、acceptまたはdenyが判定されます。
フィールド値(複数行はMultiValued) | 正規表現 | ドキュメントを受け入れるか拒否するか |
---|---|---|
{!lucene q.op=AND df=myfield}hello, Solr! | accept={!.}. | accept |
hello, Solr! | accept={!.}. | deny |
(null) | accept={!.}. | deny |
hello, Solr! | deny={!.}. | accept |
{!lucene q.op=AND df=myfield}hello, Solr! | deny={!.}. | deny |
(null) | deny={!.}. | accept |
hello, Lucene! {!lucene q.op=AND df=myfield}hello, Solr! |
accept={!.}. | accept |
hello, Solr! hello, Lucene! |
accept={!.}. | deny |
hello, Solr! hello, Lucene! |
deny={!.}. | accept |
hello, Lucene! {!lucene q.op=AND df=myfield}hello, Solr! |
deny={!.}. | deny |
solrconfig.xmlの設定:
<updateRequestProcessorChain name="regexAccept">
<processor class="com.rondhuit.solr.update.RegexCheckFieldUpdateProcessorFactory">
<str name="field">text_sm</str>
<str name="accept">\{!.*\}.*</str>
</processor>
<processor class="solr.RunUpdateProcessorFactory" />
<processor class="solr.LogUpdateProcessorFactory" />
</updateRequestProcessorChain>
<updateRequestProcessorChain name="regexDeny">
<processor class="com.rondhuit.solr.update.RegexCheckFieldUpdateProcessorFactory">
<str name="field">text_sm</str>
<str name="deny">\{!.*\}.*</str>
</processor>
<processor class="solr.RunUpdateProcessorFactory" />
<processor class="solr.LogUpdateProcessorFactory" />
</updateRequestProcessorChain>
srcのソースフィールドの一部の文字列をpatternの正規表現とreplacementで抽出し、destのフィールドにコピーしてdestフィールドを作成します。複数のフィールドの一部を組み合わせてIDフィールドを作成するようなときに用いることができます。
dest フィールドが multiValued か否か、connectionStr 指定のあるなしの組み合わせで、次の4通りの動作となります。
dest | connectionStr | 説明 |
---|---|---|
multiValued == true | なし | multiValuedでコピー |
multiValued == true | あり | connectionStrで接続しながら一行にコピー |
multiValued == false | なし | connectionStrで接続しながら一行にコピー |
multiValued == false | あり | connectionStrで接続しながら一行にコピー |
overwrite | 説明 |
---|---|
true | destフィールドに値があってもsrcから生成した文字列で上書きコピーする。 |
false(デフォルト) | destフィールドに値があるときは、その値を採用する。 |
solrconfig.xmlの設定:
<updateRequestProcessorChain name="copy">
<processor class="com.rondhuit.solr.update.RegexCopyUpdateProcessorFactory">
<lst>
<str name="dest">id1_s</str>
<bool name="overwrite">true</bool>
<str name="connectionStr">#</str>
<arr name="srcs">
<lst name="src">
<str name="name">f1_s</str>
<str name="pattern">(.*)</str>
<str name="replacement">$1</str>
</lst>
<lst name="src">
<str name="name">f2_s</str>
<str name="pattern">.(.).*</str>
<str name="replacement">$1</str>
</lst>
</arr>
</lst>
<lst>
<str name="dest">id2_s</str>
<lst name="src">
<str name="name">f3_s</str>
<str name="pattern">\s+(.+)#(.+)</str>
<str name="replacement">$2$1</str>
</lst>
</lst>
<lst>
<str name="dest">id3_sm</str>
<arr name="srcs">
<lst name="src">
<str name="name">f1_s</str>
<str name="pattern">(.*)</str>
<str name="replacement">$1</str>
</lst>
<lst name="src">
<str name="name">f2_s</str>
<str name="pattern">.(.).*</str>
<str name="replacement">$1</str>
</lst>
</arr>
</lst>
<lst>
<str name="dest">id4_sm</str>
<str name="connectionStr">#</str>
<arr name="srcs">
<lst name="src">
<str name="name">f1_s</str>
<str name="pattern">(.*)</str>
<str name="replacement">$1</str>
</lst>
<lst name="src">
<str name="name">f2_s</str>
<str name="pattern">.(.).*</str>
<str name="replacement">$1</str>
</lst>
</arr>
</lst>
</processor>
<processor class="solr.RunUpdateProcessorFactory" />
<processor class="solr.LogUpdateProcessorFactory" />
</updateRequestProcessorChain>
上記設定の下、以下のように抽出されます。
src | dest | 説明 |
---|---|---|
f1_s=”Hello!” f2_s=”1234567890″ |
old id1_s=”existData” new id1_s=”Hello!#2″ |
f1_s全体とf2_sの二番目文字のみconnectionStr=#で連結。overwrite=trueのため元のフィールド値は上書き |
f3_s=” 123#4567890″ | old id2_s=”existData” new id2_s=”existData” |
overwrite=falseのため元のフィールド値を保持。もし、overwrite=trueだったとしたら、f3_sで”#”前後の文字列を逆に連結し、id2_s=”4567890123″となる |
f1_s=”Hello!” f2_s=”1234567890″ |
id3_sm= “Hello!” “2” |
connectionStrが設定されていないのでmultiValuedでコピー |
f1_s=”Hello!” f2_s=”1234567890″ |
id4_sm=”Hello!#2″ | f1_s全体とf2_sの二番目文字のみconnectionStr=#で連結 |
fieldで指定したフィールドのURL文字列値をURLDecoder.decode(String, String)を使ってURLデコードします。encoding(デフォルトはUTF-8)でエンコーディングを指定します。
変換前 | 変換後 |
---|---|
http://www.rondhuit.con/ %E6%9C%80%E5%88%9D%E3%81%AE%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80/ %E6%AC%A1%E3%81%AE%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80/index.html |
http://www.rondhuit.con/最初のフォルダ/次のフォルダ/index.html |
solrconfig.xmlの設定:
<updateRequestProcessorChain name="url">
<processor class="com.rondhuit.solr.update.URLDecodeUpdateProcessorFactory">
<str name="field">url_s</str>
<str name="encoding">UTF-8</str>
</processor>
<processor class="solr.RunUpdateProcessorFactory" />
<processor class="solr.LogUpdateProcessorFactory" />
</updateRequestProcessorChain>
srcのnameソースフィールドの日付文字列をUTCに変換してdestのフィールドを作成します。ソースフィールドの日付文字列は、いかなるタイムゾーンを用いて表現されていてもよいです。destへはUTCに変換されます。ソースフィールドのタイムゾーンはsrcのtimezoneで指定します。また、ソースフィールドの日付文字列の書式は、srcのformatsに複数指定できます。書式は、SimpleDateFormatに従います。使用可能な書式(MMMなど)は、Solrサーバのロケールによって制限を受けます。
src | desc |
---|---|
2010/1/10 | 2010-01-09T15:00:00Z |
2010/1/10 12:34:56 | 2010-01-10T03:34:56Z |
2010-2-10 | 2010-02-09T15:00:00Z |
2010-2-10 12:34:56 | 2010-02-10T03:34:56Z |
2010年3月10日 | 2010-03-09T15:00:00Z |
2010年3月10日 12:34:56 | 2010-03-10T03:34:56Z |
solrconfig.xmlの設定:
<updateRequestProcessorChain name="utc">
<processor class="com.rondhuit.solr.update.UTCNormalizeUpdateProcessorFactory">
<str name="dest">utc_dt</str>
<lst name="src">
<str name="name">srcdt_s</str>
<str name="timezone">JST</str>
<arr name="formats">
<str>yyyy/MM/dd HH:mm:ss</str>
<str>yyyy/MM/dd</str>
<str>yyyy-MM-dd HH:mm:ss</str>
<str>yyyy-MM-dd</str>
<str>yyyy年MM月dd日 HH:mm:ss</str>
<str>yyyy年MM月dd日</str>
</arr>
</lst>
</processor>
<processor class="solr.RunUpdateProcessorFactory" />
<processor class="solr.LogUpdateProcessorFactory" />
</updateRequestProcessorChain>
dest パラメータは必須で、UTC日付文字列として生成するフィールド名を指定します。src は以下の通りです。
パラメータ | 説明 |
---|---|
name(必須) | UTC日付に変換される元のフィールド名 |
timezone | nameの日付フィールドのtimezoneに指定可能なタイムゾーンID。省略した場合は、Solrサーバが稼働しているマシンのタイムゾーンとなる |
formats(必須) | nameの日付フィールドの書式を1つ以上指定する。複数指定することで、nameフィールドの日付書式が数パターンあっても対応できる。書式は、SimpleDateFormatに従う |
LengthAwareEDisMaxQParserPlugin は検索キーワードの文字列長を見て、「なるべくフレーズ検索が発生しないように」 edismax を呼び出すラッパーです。再現率と精度の両取りを狙った日本語検索のための形態素解析と文字N-gramを対象にしたフィールドの横断検索において、(検索応答時間という意味での)パフォーマンス向上を図ることができます。
<queryParser name="lengthAwareEDisMax" class="com.rondhuit.solr.search.LengthAwareEDisMaxQParserPlugin">
<lst name="qf">
<str name="1">title_1g^5 title^10 body_1g body^2</str>
<str name="2">title_2g^5 title^10 body_2g body^2</str>
<str name="3">title_3g^5 title^10 body_3g body^2</str>
</lst>
</queryParser>
LengthAwareEDisMaxQParserPlugin は edismax と同じく横断検索したいフィールド名を qf パラメータに重み付きで指定します。ただし、edismax と異なるのは、検索キーワードの長さ毎に複数指定できる点です。つまり、上記を例に取れば、検索キーワードの長さが1であればフィールド(および重み、以下同じ)title_k1^5 title^10 body_k1 body^2を対象に、検索キーワードの長さが2であればフィールドtitle_2g^5 title^10 body_2g body^2を対象に、検索キーワードの長さが3であればフィールドtitle_3g^5 title^10 body_3g body^2を対象に検索するよう、edismax クエリに展開します。では検索キーワードの長さが4以上の場合はどうなるかというと、一番近い設定、つまり上記であれば3の設定が使われます。
このようにすることで極力重い処理であるフレーズクエリの発生を抑え、検索パフォーマンスが落ちないようにしています。
検索リクエスト時は、typeに”lengthAwareEDisMax”を指定したlocalParamsを用います。
http://localhost:8983/solr/basic/select?q={!lengthAwareEDisMax}魂 日本
このとき設定が前述の通りであれば、次のようなクエリ展開がなされてedismaxが呼び出されます:
title_1g:魂^5 title:魂^10 body_1g:魂 body:魂^2 title_2g:日本^5 title:日本^10 body_2g::日本 body::日本^2
辞書ベースのクエリ書き換えを行う QParserPlugin の実装です。本機能により、1行1単語のテキストファイル(辞書ファイル)を用意することで、特定のクエリを特定のフィールドに投げることができるようになります。クエリを「東京ディズニーランド」とし、辞書に「東京」が含まれている時のクエリのイメージは以下の通りです。
項目 | |
---|---|
クエリ | 東京ディズニーランド |
クエリ内で辞書にヒットした文字列 | 東京 |
生成されるクエリ | (edismax:(東京ディズニーランド)) OR (edismax:(特定フィールド:(東京))) |
solrconfig.xml に記述する例を以下に記します。
<queryParser name="edismaxEx" class="com.rondhuit.solr.search.EDisMaxExQParserPlugin">
<lst name="person">
<str name="dic">people.txt</str>
<bool name="remove">true</bool>
<str name="fields">speaker^3 title</str>
</lst>
<lst name="location">
<str name="dic">locations.txt</str>
<str name="fields">statement^2 title</str>
</lst>
</queryParser>
...
<requestHandler name="/select" class="solr.SearchHandler">
...
<str name="defType">edismaxEx</str>
...
</requestHandler>
各属性値と要素の内容について記します。尚、lst タグの属性値と属性名は動作には直接関係しない部分です。name 属性には”location”など任意の属性値を記述して下さい。lst タグは64個まで記述することが可能です。辞書ファイル1つに対し、1つの lst タグを記述します。
dic(必須) | 説明 |
---|---|
ファイル名 | 辞書ファイル名のみを記述します。 |
remove(オプション) | 説明 |
---|---|
true | 辞書に該当する文字列をクエリから削除して検索します |
false(デフォルト) | 辞書に該当する文字列をクエリから削除せずに検索します |
fields(必須) | 説明 |
---|---|
適用フィールド | 辞書にヒットしたクエリが投げられるフィールド名を記述します。フィールドは複数記述することができ、ブースト値も指定できます。 例:field_1^5.0 field_2^3.0 |
上記 solrconfig.xml の設定で、属性値 dic に指定する辞書ファイルの内容を記します。辞書ファイルはテキストファイルとし、以下のフォーマットで記述します。
単語1
単語2
単語3
:
(例)
東京
横浜
大阪
上記のように、1行1単語で記述します。
作成した辞書ファイルは、RCSS の以下のディレクトリ内に配置します。
$RCSS/LUSOLR/solr/server/resources
CheckIndexSubsetComponent は fields に指定された1つ以上のフィールドに対して、検索時に fq が指定されていることを確認し、指定されていない場合は例外を発生させて検索が実行されないようにする SearchComponent です。AddFieldsFromRequestParametersUpdateRequestProcessor と組み合わせて使うことで、シングルコア環境でマルチテナントを実現するのに便利です。
CheckIndexSubsetComponent は次のように、searchComponent を設定するところで、fq を行うフィールド名を fields パラメータで指定します。また、QueryComponent より後ろに実行されるよう、requestHandler の設定を行います。そのため、以下の例では last-components を使っています。
<searchComponent name="checkfq" class="com.rondhuit.solr.search.CheckIndexSubsetComponent" >
<arr name="fields">
<str>tenant</str>
<str>department</str>
</arr>
</searchComponent>
<requestHandler name="/useCheckfq" class="org.apache.solr.handler.component.SearchHandler">
<arr name="last-components">
<str>checkfq</str>
</arr>
</requestHandler>
以上の設定の下、次のように検索を実行すると、tenant フィールドに対してテナントを絞り込む検索である fq が指定されていないので、例外が発生し検索が実行されません。
http://localhost:8983/solr/basic/useCheckfq?q=*:*&fq=department:software
次のようにテナントを絞り込む fq を指定すれば、エラーは起こらなくなります。
http://localhost:8983/solr/basic/useCheckfq?q=*:*&fq=tenant:RONDHUIT&fq=department:software