尝试实现基于 edismax 类型的自动完成时收到以下错误。
SEVERE: java.lang.IllegalStateException: field "locality_ng" was indexed without position data; cannot run PhraseQuery (term=львів)
at org.apache.lucene.search.PhraseQuery$PhraseWeight.scorer(PhraseQuery.java:241)
at org.apache.lucene.search.DisjunctionMaxQuery$DisjunctionMaxWeight.scorer(DisjunctionMaxQuery.java:145)
at org.apache.lucene.search.BooleanQuery$BooleanWeight.scorer(BooleanQuery.java:317)
at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:551)
at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:324)
at org.apache.solr.search.SolrIndexSearcher.getDocListNC(SolrIndexSearcher.java:1275)
架构类型:
<fieldType name="text_suggest" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<!--charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ISOLatin1Accent.txt"/-->
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="1" splitOnCaseChange="1" splitOnNumerics="1" preserveOriginal="1" />
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
<analyzer type="query">
<!--charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ISOLatin1Accent.txt"/-->
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="0" generateNumberParts="0" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="0" splitOnNumerics="0"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
<!-- autocomplete_edge : Will match from the left of the field, e.g. if the document field
is "A brown fox" and the query is "A bro", it will match, but not "brown"
-->
<fieldType name="autocomplete_edge" class="solr.TextField">
<analyzer type="index">
<!--charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ISOLatin1Accent.txt"/-->
<tokenizer class="solr.KeywordTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.PatternReplaceFilterFactory" pattern="([.,;:_])" replacement=" " replace="all"/>
<filter class="solr.EdgeNGramFilterFactory" maxGramSize="50" minGramSize="2"/>
</analyzer>
<analyzer type="query">
<!--charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ISOLatin1Accent.txt"/-->
<tokenizer class="solr.KeywordTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.PatternReplaceFilterFactory" pattern="([.,;:_])" replacement=" " replace="all"/>
<filter class="solr.PatternReplaceFilterFactory" pattern="^(.{50})(.*)?" replacement="$1" replace="all"/>
</analyzer>
</fieldType>
<!-- autocomplete_ngram : Matches any word in the input field, with implicit right truncation.
This means that the field "A brown fox" will be matched by query "bro".
We use this to get partial matches, but these whould be boosted lower than exact and left-anchored
-->
<fieldType name="autocomplete_ngram" class="solr.TextField">
<analyzer type="index">
<!--charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ISOLatin1Accent.txt"/-->
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="0" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="1"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.EdgeNGramFilterFactory" maxGramSize="20" minGramSize="2"/>
</analyzer>
<analyzer type="query">
<!--charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ISOLatin1Accent.txt"/-->
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="0" generateNumberParts="0" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="0"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.PatternReplaceFilterFactory" pattern="^(.{20})(.*)?" replacement="$1" replace="all"/>
</analyzer>
</fieldType>
架构字段
<!-- AutoComplete fields
Construct documents containing these fields for all suggestions you like to provide
Then use a dismax query to search on some fields, display some fields and boost others
-->
<field name="locality_id" type="int" indexed="true" stored="true" required="true"/>
<!-- The main text to return as the suggestion. This is not searched -->
<field name="locality_suggest" type="text_suggest" indexed="true" stored="true" omitNorms="true" multiValued="true" />
<!-- A variant of textsuggest which only matches from the very left edge -->
<copyField source="locality_suggest" dest="locality_nge"/>
<field name="locality_nge" type="autocomplete_edge" indexed="true" stored="false" multiValued="true" />
<!-- A variant of textsuggest which matches from the left edge of all terms (implicit truncation) -->
<copyField source="locality_suggest" dest="locality_ng"/>
<field name="locality_ng" type="autocomplete_ngram" indexed="true" stored="false" omitNorms="true" omitTermFreqAndPositions="true" multiValued="true" />
Solr 配置,使用以下具有 EDISMAX 类型的请求处理程序:
<requestHandler class="solr.SearchHandler" name="autocomplete" >
<lst name="defaults">
<str name="defType">edismax</str>
<str name="rows">10</str>
<str name="fl">*,score</str>
<str name="qf">locality_suggest locality_ng^5.0 locality_nge^10.0</str>
<str name="debugQuery">false</str>
</lst>
仅当查询包含特定符号(如单词后 + - $ @)时,才会发生此错误
львів+вкиїв+а
任何建议都会很棒
更改
<field name="locality_ng" type="autocomplete_ngram" indexed="true" stored="false" omitNorms="true" omitTermFreqAndPositions="true" multiValued="true" />
到
<field name="locality_ng" type="autocomplete_ngram" indexed="true" stored="false" omitNorms="true" multiValued="true" />