web-dev-qa-db-ja.com

SOLRで文字列フィールドの大文字と小文字を区別しないコピーを作成する方法は?

大文字と小文字を区別しない形式で文字列フィールドのコピーを作成するにはどうすればよいですか?典型的な「文字列」型と大文字小文字を区別しない型を使用したいと思います。タイプは次のように定義されています。

    <fieldType name="string" class="solr.StrField"
        sortMissingLast="true" omitNorms="true" />

    <!-- A Case insensitive version of string type  -->
    <fieldType name="string_ci" class="solr.StrField"
        sortMissingLast="true" omitNorms="true">
        <analyzer type="index">
            <tokenizer class="solr.KeywordTokenizerFactory"/>           
            <filter class="solr.LowerCaseFilterFactory" />
        </analyzer>
        <analyzer type="query">
            <tokenizer class="solr.KeywordTokenizerFactory"/>
            <filter class="solr.LowerCaseFilterFactory" />
        </analyzer>
    </fieldType> 

そして、そのようなフィールドの例:

<field name="destANYStr" type="string" indexed="true" stored="true"
    multiValued="true" />
<!-- Case insensitive version -->
<field name="destANYStrCI" type="string_ci" indexed="true" stored="false" 
    multiValued="true" />

私は次のようにCopyFieldを使用してみました:

<copyField source="destANYStr" dest="destANYStrCI" />

ただし、CopyFieldは、アナライザーが呼び出される前に、sourceおよびdestで呼び出されるようです。そのため、アナライザーでdestが大文字と小文字を区別しないことを指定した場合でも、sourceフィールドからコピーされた値の大文字と小文字は保持されます。

レコード作成時に、クライアントからフィールドの値を再送信しないことを望んでいます。

26
harschware

SOからの回答なしで、SOLRユーザーリストをフォローアップしました。私のstring_ciフィールドは、copyFieldの影響を考慮する前でも期待どおりに機能していなかったことがわかりました。 Ahmet Arslanは、「string_ci」フィールドがsolr.StrFieldではなくsolr.TextFieldを使用する必要がある理由を説明しています。

Apache-solr-1.4.0\example\solr\conf\schema.xmlから:

「StrFieldタイプは分析されませんが、インデックス化/保存されたとおりです。」

「solr.TextFieldを使用すると、トークナイザーおよびトークンフィルターのリストとして指定されたカスタムテキストアナラ​​イザーを指定できます。」

彼が提供した例と私自身によるわずかな調整により、次のフィールド定義がうまくいくように見え、CopyFieldも期待どおりに機能します。

    <fieldType name="string_ci" class="solr.TextField"
        sortMissingLast="true" omitNorms="true">
        <analyzer>
            <tokenizer class="solr.KeywordTokenizerFactory"/>           
            <filter class="solr.LowerCaseFilterFactory" />
        </analyzer>
    </fieldType> 

DestANYStrCIフィールドには、大文字と小文字が保存された値が格納されますが、大文字と小文字を区別しないフィールドで検索できます。警告:ワイルドカードフレーズはクエリアナライザーをバイパスし、インデックスと照合する前に小文字に変換されないため、大文字と小文字を区別しないワイルドカード検索は実行できません。つまり、ワイルドカードフレーズの文字は、一致するために小文字でなければなりません。

53
harschware

そうですね。 LowerCaseFilterFactoryは、Stringデータ型には適用されません。 LowerCaseFilterFactoryを適用できるのはテキストフィールドのみです。

このようにしようとすると

<!-- Assigning customised data type -->
<field name="language" type="text_lower" indexed="true" stored="true"  multiValued="false" default="en"/>  

<!-- Defining customised data type for lower casing. -->
<fieldType name="text_lower" class="solr.String" positionIncrementGap="100">
  <analyzer type="index">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
  <analyzer type="query">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
</fieldType>

これは機能しません。TextFieldを使用する必要があります。

この方法を試してみてください。うまくいくはずです。 fieldTypeをStringからTextFieldに変更するだけです

<!-- Assigning customised data type -->
<field name="language" type="text_lower" indexed="true" stored="true"  multiValued="false" default="en"/>  

<!-- Defining customised data type for lower casing. -->
<fieldType name="text_lower" class="solr.TextField" positionIncrementGap="100">
  <analyzer type="index">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
  <analyzer type="query">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
</fieldType>
7
Manjunath Reddy