0

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 config では、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>

このエラーは、クエリに単語の後に + - $ @ などの特定の記号が含まれている場合にのみ発生しました

львів+в київ+а

どんな提案も素晴らしいでしょう

4

1 に答える 1