Подтвердить что ты не робот

Как создать нечувствительную к регистру копию поля строки в SOLR?

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

    <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 вызывается в источнике и dest перед вызовом любых анализаторов, поэтому, хотя я указал, что dest не учитывает регистр через anaylyzers, сохраняется регистр значений, скопированных из исходного поля.

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

4b9b3361

Ответ 1

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

Ответ 2

Да true. 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>