Я не знаю способа динамического повышения в зависимости от длины термина (т. Е. С помощью оператора Function Query). Я подозреваю, что нет ни одного.
Тем не менее, я часто хочу аппроксимировать логику, которую вы ищете: долгосрочные совпадения заслуживают более высокого смыслового веса.
Чаще всего я буду индексировать текстовое значение в двух разных полях. Одним из них является минимально обработанное текстовое поле без нграмм. Другое похоже, но также обрабатывается с помощью ngrams.
Вот некоторые примеры выдержек из схемы, которую я использовал таким образом. Для поиска по этой схеме я бы сильно увеличил поле text
по сравнению с text_ngram
. Таким образом, любые совпадения с полем text
могут сильно повлиять на релевантность, в то время как совпадения с text_ngram
могут все еще собирать и релевантные результаты.
<?xml version="1.0" encoding="UTF-8"?>
<schema name="Sunspot Customized NZ" version="1.0">
<types>
<!--
A text type with minimal text processing, for the greatest semantic
value in a term match. Boost this field heavily.
-->
<fieldType name="text" class="solr.TextField" omitNorms="false">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory" />
<filter class="solr.StandardFilterFactory" />
<filter class="solr.LowerCaseFilterFactory" />
</analyzer>
</fieldType>
<!--
Looser matches with NGram processing for substrings of terms and synonyms
-->
<fieldType name="text_ngram" class="solr.TextField" omitNorms="false">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory" />
<filter class="solr.StandardFilterFactory" />
<filter class="solr.LowerCaseFilterFactory" />
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true" />
<filter class="solr.EdgeNGramFilterFactory" minGramSize="1" maxGramSize="6" side="front" />
</analyzer>
</fieldType>
<!-- other stuff -->
</types>
<fields>
<!-- id, other scalar values -->
<!-- catch-all for the text and text_ngram types -->
<field name="text" stored="false" type="text" multiValued="true" indexed="true" />
<field name="text_ngram" stored="false" type="text_ngram" multiValued="true" indexed="true" />
<!-- various dynamicField definitions -->
<!-- sample dynamicField definitions for text and text_ngram -->
<dynamicField name="*_text" type="text" indexed="true" stored="false" multiValued="false" />
<dynamicField name="*_text_ngram" type="text_ngram" indexed="true" stored="false" multiValued="false" />
</fields>
<!-- copy text fields into my text and text_ngram catch-all fields -->
<copyField source="*_text" dest="text" />
<copyField source="*_text" dest="text_ngram" />
</schema>
Это не совсем то, что вы ищете, но вы можете использовать аналогичный подход.
Например, создайте небольшую коллекцию промежуточных типов полей, обработанных NGram, скажем, длиной 1-3, 4-6, 7-9, и соответственно увеличьте их.