Solr Search 8.4.1 не находит результатов - PullRequest
0 голосов
/ 02 марта 2020

У меня проблема с настройкой Solr Search. Я новичок в Solr, но считаю, что проблема связана с файлом solrconfig. xml. Но, пожалуйста, скажите мне, если я ошибаюсь!

Проблема в том, что, если я ввожу поиск в поле q на странице администрирования Solr, я получаю 0 результатов. Однако, если я набираю запрос с подстановочными знаками, например *"query"*, я возвращаю все документы в базе данных. Вот файл solrconfig. xml, который у меня есть:

<?xml version="1.0" encoding="UTF-8"?>
<config>
  <luceneMatchVersion>8.4.1</luceneMatchVersion>

  <dataDir>${solr.data.dir:}</dataDir>

  <directoryFactory name="DirectoryFactory"
                    class="${solr.directoryFactory:solr.NRTCachingDirectoryFactory}"/>

  <codecFactory class="solr.SchemaCodecFactory"/>

  <schemaFactory class="ClassicIndexSchemaFactory"/>

  <updateHandler class="solr.DirectUpdateHandler2">

    <updateLog>
      <str name="dir">${solr.ulog.dir:}</str>
      <int name="numVersionBuckets">${solr.ulog.numVersionBuckets:65536}</int>
    </updateLog>

    <autoCommit>
      <maxTime>${solr.autoCommit.maxTime:15000}</maxTime>
      <openSearcher>false</openSearcher>
    </autoCommit>

    <autoSoftCommit>
      <maxTime>${solr.autoSoftCommit.maxTime:-1}</maxTime>
    </autoSoftCommit>

  </updateHandler>

  <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       Query section - these settings control query time things like caches
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
  <query>

    <maxBooleanClauses>${solr.max.booleanClauses:1024}</maxBooleanClauses>

    <filterCache class="solr.FastLRUCache"
                 size="512"
                 initialSize="512"
                 autowarmCount="0"/>

    <queryResultCache class="solr.LRUCache"
                      size="512"
                      initialSize="512"
                      autowarmCount="0"/>

    <documentCache class="solr.LRUCache"
                   size="512"
                   initialSize="512"
                   autowarmCount="0"/>

    <!-- custom cache currently used by block join -->
    <cache name="perSegFilter"
           class="solr.search.LRUCache"
           size="10"
           initialSize="0"
           autowarmCount="10"
           regenerator="solr.NoOpRegenerator" />

    <enableLazyFieldLoading>true</enableLazyFieldLoading>

    <queryResultWindowSize>20</queryResultWindowSize>

    <queryResultMaxDocsCached>200</queryResultMaxDocsCached>
    <listener event="newSearcher" class="solr.QuerySenderListener">
      <arr name="queries">
      </arr>
    </listener>
    <listener event="firstSearcher" class="solr.QuerySenderListener">
      <arr name="queries">
      </arr>
    </listener>

    <useColdSearcher>false</useColdSearcher>

  </query>

  <requestDispatcher>
    <httpCaching never304="true" />
  </requestDispatcher>

  <requestHandler name="/select" class="solr.SearchHandler">
    <!-- <lst name="defaults"> -->
      <!-- <str name="echoParams">explicit</str> -->
      <!-- <int name="rows">10</int> -->
    <!-- </lst> -->
  </requestHandler>  

  <requestHandler name="/query" class="solr.SearchHandler">
    <lst name="defaults">
      <str name="echoParams">explicit</str>
      <str name="wt">json</str>
      <str name="indent">true</str>
    </lst>
  </requestHandler>

  <initParams path="/update/**,/query,/select,/spell">
    <lst name="defaults">
      <str name="df">_text_</str>
    </lst>
  </initParams>

  <searchComponent name="spellcheck" class="solr.SpellCheckComponent">
    <str name="queryAnalyzerFieldType">text_general</str>
    <!-- a spellchecker built from a field of the main index -->
    <lst name="spellchecker">
      <str name="name">default</str>
      <str name="field">_text_</str>
      <str name="classname">solr.DirectSolrSpellChecker</str>
      <!-- the spellcheck distance measure used, the default is the internal levenshtein -->
      <str name="distanceMeasure">internal</str>
      <!-- minimum accuracy needed to be considered a valid spellcheck suggestion -->
      <float name="accuracy">0.5</float>
      <!-- the maximum #edits we consider when enumerating terms: can be 1 or 2 -->
      <int name="maxEdits">2</int>
      <!-- the minimum shared prefix when enumerating terms -->
      <int name="minPrefix">1</int>
      <!-- maximum number of inspections per result. -->
      <int name="maxInspections">5</int>
      <!-- minimum length of a query term to be considered for correction -->
      <int name="minQueryLength">4</int>
      <!-- maximum threshold of documents a query term can appear to be considered for correction -->
      <float name="maxQueryFrequency">0.01</float>
    </lst>
  </searchComponent>  

  <requestHandler name="/spell" class="solr.SearchHandler" startup="lazy">
    <lst name="defaults">
      <str name="spellcheck.dictionary">default</str>
      <str name="spellcheck">on</str>
      <str name="spellcheck.extendedResults">true</str>
      <str name="spellcheck.count">10</str>
      <str name="spellcheck.alternativeTermCount">5</str>
      <str name="spellcheck.maxResultsForSuggest">5</str>
      <str name="spellcheck.collate">true</str>
      <str name="spellcheck.collateExtendedResults">true</str>
      <str name="spellcheck.maxCollationTries">10</str>
      <str name="spellcheck.maxCollations">5</str>
    </lst>
    <arr name="last-components">
      <str>spellcheck</str>
    </arr>
  </requestHandler>

  <searchComponent name="terms" class="solr.TermsComponent"/>

  <!-- A request handler for demonstrating the terms component -->
  <requestHandler name="/terms" class="solr.SearchHandler" startup="lazy">
    <lst name="defaults">
      <bool name="terms">true</bool>
      <bool name="distrib">false</bool>
    </lst>
    <arr name="components">
      <str>terms</str>
    </arr>
  </requestHandler>

  <searchComponent class="solr.HighlightComponent" name="highlight">
    <highlighting>
      <!-- Configure the standard fragmenter -->
      <!-- This could most likely be commented out in the "default" case -->
      <fragmenter name="gap"
                  default="true"
                  class="solr.highlight.GapFragmenter">
        <lst name="defaults">
          <int name="hl.fragsize">100</int>
        </lst>
      </fragmenter>

      <!-- A regular-expression-based fragmenter
           (for sentence extraction)
        -->
      <fragmenter name="regex"
                  class="solr.highlight.RegexFragmenter">
        <lst name="defaults">
          <!-- slightly smaller fragsizes work better because of slop -->
          <int name="hl.fragsize">70</int>
          <!-- allow 50% slop on fragment sizes -->
          <float name="hl.regex.slop">0.5</float>
          <!-- a basic sentence pattern -->
          <str name="hl.regex.pattern">[-\w ,/\n\&quot;&apos;]{20,200}</str>
        </lst>
      </fragmenter>

      <!-- Configure the standard formatter -->
      <formatter name="html"
                 default="true"
                 class="solr.highlight.HtmlFormatter">
        <lst name="defaults">
          <str name="hl.simple.pre"><![CDATA[<em>]]></str>
          <str name="hl.simple.post"><![CDATA[</em>]]></str>
        </lst>
      </formatter>

      <!-- Configure the standard encoder -->
      <encoder name="html"
               class="solr.highlight.HtmlEncoder" />

      <!-- Configure the standard fragListBuilder -->
      <fragListBuilder name="simple"
                       class="solr.highlight.SimpleFragListBuilder"/>

      <!-- Configure the single fragListBuilder -->
      <fragListBuilder name="single"
                       class="solr.highlight.SingleFragListBuilder"/>

      <!-- Configure the weighted fragListBuilder -->
      <fragListBuilder name="weighted"
                       default="true"
                       class="solr.highlight.WeightedFragListBuilder"/>

      <!-- default tag FragmentsBuilder -->
      <fragmentsBuilder name="default"
                        default="true"
                        class="solr.highlight.ScoreOrderFragmentsBuilder">
        <!--
        <lst name="defaults">
          <str name="hl.multiValuedSeparatorChar">/</str>
        </lst>
        -->
      </fragmentsBuilder>

      <!-- multi-colored tag FragmentsBuilder -->
      <fragmentsBuilder name="colored"
                        class="solr.highlight.ScoreOrderFragmentsBuilder">
        <lst name="defaults">
          <str name="hl.tag.pre"><![CDATA[
               <b style="background:yellow">,<b style="background:lawgreen">,
               <b style="background:aquamarine">,<b style="background:magenta">,
               <b style="background:palegreen">,<b style="background:coral">,
               <b style="background:wheat">,<b style="background:khaki">,
               <b style="background:lime">,<b style="background:deepskyblue">]]></str>
          <str name="hl.tag.post"><![CDATA[</b>]]></str>
        </lst>
      </fragmentsBuilder>

      <boundaryScanner name="default"
                       default="true"
                       class="solr.highlight.SimpleBoundaryScanner">
        <lst name="defaults">
          <str name="hl.bs.maxScan">10</str>
          <str name="hl.bs.chars">.,!? &#9;&#10;&#13;</str>
        </lst>
      </boundaryScanner>

      <boundaryScanner name="breakIterator"
                       class="solr.highlight.BreakIteratorBoundaryScanner">
        <lst name="defaults">
          <!-- type should be one of CHARACTER, WORD(default), LINE and SENTENCE -->
          <str name="hl.bs.type">WORD</str>
          <!-- language and country are used when constructing Locale object.  -->
          <!-- And the Locale object will be used when getting instance of BreakIterator -->
          <str name="hl.bs.language">en</str>
          <str name="hl.bs.country">US</str>
        </lst>
      </boundaryScanner>
    </highlighting>
  </searchComponent>  

  <searchComponent name="query" class="org.apache.solr.handler.component.QueryComponent" />
</config>

А вот схема. xml file:

<?xml version="1.0" encoding="UTF-8"?>
<schema name='test2' version='1.1'>
    <types>
        <fieldtype name='string' class='solr.StrField' />
        <fieldtype name='long' class='solr.TrieLongField' />
        <fieldType name="plong" class="solr.LongPointField" docValues="true" />
        <fieldType name="text" class="solr.TextField"/> 
    </types>

    <fields>
        <field name='id' type='long' required='true' />
        <field name="_version_" type="plong" indexed="false" stored="true"/>
        <field name='title' type='text' />
        <field name='parentCategory' type='text' />
        <field name='childCategory' type='text' />
        <field name='body' type='text' />
        <field name='url' type='text' />

        <dynamicField name='*_string' type='text' multiValued='true' indexed='true' stored='true' />
        <copyField source='*' dest='_text_' />
        <field name='_text_' type='text' indexed='true' multiValued='true' stored='true' />
    </fields>

    <uniqueKey>id</uniqueKey>
    <df>_text_</df>
    <solrQueryParser q.op='OR' />
</schema>

Может ли кто-нибудь помочь мне заставить поиск работать здесь? ?

Редактировать: Использование точных фраз работает. Например, если у меня есть заголовок «Test Title», и я использую поисковую фразу title:"Test Title", она работает, как и ожидалось. Но я должен иметь возможность использовать поисковый запрос: title:"test" и иметь те же результаты.

Ответы [ 2 ]

0 голосов
/ 02 марта 2020

Из вашего schema.xml нет никаких причин, по которым нужно что-либо сопоставлять, кроме точных попаданий. В вашем TextField нет токенайзера (который разбивает текст на слова / токены) или каких-либо фильтров (которые обрабатывают текст далее).

Вместо этого вы, вероятно, захотите основывать свое поле на одном из доступных типов text_ в конфигурации по умолчанию, например, text_general:

<fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
  <analyzer type="index"> 
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
    <!-- in this example, we will only use synonyms at query time
    <filter class="solr.SynonymFilterFactory" synonyms="index_synonyms.txt" ignoreCase="true" expand="false"/>
    -->
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
  <analyzer type="query">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
    <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
</fieldType>

Это разделит ваш текст на отдельные токены на несколько различных символов (например, пробел, - и т. Д.). c.), Затем примените StopFilter (удалив the и другие не относящиеся к делу слова) и, наконец, примените LowerCaseFilter - это означает, что при сопоставлении все будет строчным. Поскольку нижний регистр происходит как при индексации, так и при запросах (заданных типами определения цепочек index и query), это делает ваш поиск на практике нечувствительным к регистру.

После внесения любых подобных изменений (в частности, для всего, что изменяет порядок индексирования контента, вы должны переиндексировать свой контент (т.е. снова отправить все документы в Solr).

0 голосов
/ 02 марта 2020

Чтобы это работало, Solr предоставляет вам несколько встроенных фильтров токенов. В вашем случае, я думаю, что EdgeNGramFilterFactory и NGramFilterFactory будут работать, так как вам нужно сопоставить частичные токены без передачи выражения Regex. Вы можете найти больше об этом по этой ссылке: https://hostedapachesolr.com/support/partial-word-match-solr-edgengramfilterfactory. Вы всегда можете настроить этот фильтр в соответствии с вашими потребностями. Если вы новичок в фильтрах в Solr, эта часть документации может вам помочь https://lucene.apache.org/solr/guide/6_6/understanding-analyzers-tokenizers-and-filters.html.

...