Как создать нечувствительную к регистру копию строкового поля в SOLR? - PullRequest
25 голосов
/ 13 января 2010

Как создать копию строкового поля в нечувствительной к регистру форме? Я хочу использовать типичный "строковый" тип и нечувствительный к регистру тип. Типы определены так:

    <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 не зависит от регистра через анализаторы, регистр значений, скопированных из поля источника, сохраняется.

Я надеюсь избежать повторной передачи значения в поле от клиента во время создания записи.

Ответы [ 2 ]

52 голосов
/ 14 января 2010

Без ответов от SO я проследил за списком пользователей SOLR. Я обнаружил, что мое поле string_ci работало не так, как ожидалось, даже прежде, чем учесть эффекты copyField. Ахмет Арслан объясняет, почему поле «string_ci» должно использовать solr.TextField, а не solr.StrField:

Из 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 будет храниться сохраненное в регистре значение, но в нем будет нечувствительное к регистру поле для поиска. CAVEAT: поиск подстановочного знака без учета регистра невозможен, так как подстановочные фразы обходят анализатор запросов и не будут переданы в нижнем регистре до сопоставления с индексом. Это означает, что символы в подстановочных словах должны совпадать в нижнем регистре.

7 голосов
/ 21 октября 2013

Да, правда. 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>
...