solr7.1.0的搜索提示功能实现

模糊匹配及Solr关键词自动提示应用http://blog.csdn.net/liangpz521/article/details/26867355

模糊匹配及Solr关键词自动提示应用http://blog.csdn.net/bingduanlbd/article/details/52198012

智能提示(一) Solr (suggest)http://blog.csdn.net/hu948162999/article/details/46729549

以上是solr7以前的实现方式,下面介绍solr-7.1.0的实现方式:

首先是配置文件的配置:

这是solr配置文件的目录:

因为APP端和PC端搜索智能提示的字段不同,所以用了两个suggestion域

managed-schema 文件的配置:

配置智能提示filed:

<field name="id" type="uuid" indexed="true" stored="true" multiValued="false" required="true" />


    <field name="suggestion" type="textSuggest" indexed="true" stored="true" required="true" multiValued="true" />
    <field name="suggestion2" type="textSuggest" indexed="true" stored="true" required="true" multiValued="true" />
    <field name="produceEnterprice" type="textSuggest" indexed="true" stored="true" required="false" multiValued="false" />
    <field name="genericName" type="textSuggest" indexed="true" stored="true" required="false" multiValued="false" />
    <field name="genericName2" type="textSuggest" indexed="true" stored="true" required="false" multiValued="false" />
    <field name="tradeName2" type="textSuggest" indexed="true" stored="true" required="false" multiValued="false" />
    <field name="tradeName" type="textSuggest" indexed="true" stored="true" required="false" multiValued="false" />
    <copyField source="genericName" dest="suggestion" maxChars="256"/>
    <copyField source="tradeName" dest="suggestion" maxChars="256"/>
    <copyField source="produceEnterprice" dest="suggestion" maxChars="256"/>
    <copyField source="genericName2" dest="suggestion2" maxChars="256"/>
    <copyField source="tradeName2" dest="suggestion2" maxChars="256"/>

配置搜索索引字段:

 <field name="medicineGoodsId" type="pint" indexed="true" stored="true" required="true" multiValued="false" />
    <field name="medicineProductId" type="pint" indexed="true" stored="true" required="false" multiValued="false" />
    <field name="imgUrl" type="string" indexed="false" stored="true" required="false" multiValued="false" />
    <field name="specification" type="string" indexed="true" stored="true" required="false" multiValued="false" />
    <field name="cateId" type="pint" indexed="true" stored="true" required="false" multiValued="false" />
    <field name="cateSecondId" type="pint" indexed="true" stored="true" required="false" multiValued="false" />
    <field name="cateThirdId" type="pint" indexed="true" stored="true" required="false" multiValued="false" />
    <field name="genericCateId" type="pint" indexed="true" stored="true" required="false" multiValued="false" />
    <field name="genericCateSecondId" type="pint" indexed="true" stored="true" required="false" multiValued="false" />
    <field name="dosageFormId" type="pint" indexed="true" stored="true" required="false" multiValued="false" />
    <field name="dosageFormName" type="string" indexed="true" stored="true" required="false" multiValued="false" />
    <field name="reimbursementType" type="string" indexed="true" stored="true" required="false" multiValued="false" />
    <field name="basicOrCommon" type="string" indexed="true" stored="false" required="false" multiValued="false" />
    <field name="approvalNum" type="string" indexed="true" stored="true" required="false" multiValued="false" />
    <field name="medicinePackage" type="string" indexed="false" stored="true" required="false" multiValued="false" />
    <field name="unitId" type="pint" indexed="true" stored="true" required="false" multiValued="false" />
    <field name="unitName" type="string" indexed="true" stored="true" required="false" multiValued="false" />
    <field name="companyId" type="pint" indexed="true" stored="true" required="false" multiValued="false" />
    <field name="companyName" type="string" indexed="true" stored="false" required="false" multiValued="false" />
    <field name="suggestedPrice" type="string" indexed="false" stored="true" required="false" multiValued="false" />
    <field name="availabilityPrice" type="string" indexed="false" stored="true" required="false" multiValued="false" />
    <field name="boxNum" type="string" indexed="true" stored="true" required="false" multiValued="false" />


    <field name="authId" type="pint" indexed="true" stored="true" required="false" multiValued="false" />
                                                                                                                                                      8,0-1         Top

    <field name="authId" type="pint" indexed="true" stored="true" required="false" multiValued="false" />
    <field name="authChannelId" type="pint" indexed="true" stored="true" required="false" multiValued="false" />
    <field name="authChannelUserId" type="pint" indexed="true" stored="true" required="false" multiValued="false" />
    <field name="authCompanyId" type="pint" indexed="true" stored="true" required="false" multiValued="false" />
    <field name="authControlDivisionId" type="pint" indexed="true" stored="true" required="false" multiValued="false" />
    <field name="authControlUserId" type="pint" indexed="true" stored="true" required="false" multiValued="false" />
    <field name="authControlChannelId" type="pint" indexed="true" stored="true" required="false" multiValued="false" />
    <field name="authDivisionMedicineId" type="pint" indexed="true" stored="true" required="false" multiValued="false" />
    <field name="authorizationPrice" type="string" indexed="false" stored="true" required="false" multiValued="false" />
    <field name="authControlCompanyId" type="string" indexed="false" stored="true" required="false" multiValued="false" />
    <uniqueKey>id</uniqueKey>

配置ik中文分词器:

<fieldType name="text_ik" class="solr.TextField" positionIncrementGap="100">
      <analyzer type="index">
        <tokenizer class="org.apache.lucene.analysis.cn.smart.HMMChineseTokenizerFactory"/>
      </analyzer>
      <analyzer type="query">
        <tokenizer class="org.apache.lucene.analysis.cn.smart.HMMChineseTokenizerFactory"/>
      </analyzer>
    </fieldType>

配置智能提示的filedType:

  <fieldType name="textSuggest" class="solr.TextField" positionIncrementGap="100">
    <analyzer type="index">
      <tokenizer class="org.apache.lucene.analysis.cn.smart.HMMChineseTokenizerFactory"/>
      <filter class="solr.LowerCaseFilterFactory"/>
    </analyzer>
    <analyzer type="query">
      <tokenizer class="org.apache.lucene.analysis.cn.smart.HMMChineseTokenizerFactory"/>
      <filter class="solr.LowerCaseFilterFactory"/>
    </analyzer>
  </fieldType>

配置自增主键uuid:

<fieldType name="uuid" class="solr.UUIDField" indexed="true" />

solrconfig.xml 的配置:(两个不同的requestHandler的配置)

<searchComponent name="suggest" class="solr.SuggestComponent">
         <lst name="suggester">
                 <str name="name">mySuggester</str>
                 <str name="lookupImpl">FuzzyLookupFactory</str>
                 <str name="dictionaryImpl">DocumentDictionaryFactory</str>
                 <str name="field">suggestion</str>
                <!-- <str name="weightField">price</str>    -->
                 <str name="suggestAnalyzerFieldType">textSuggest</str>
                 <str name="buildOnStartup">false</str>
         </lst>
        </searchComponent>

        <requestHandler name="/suggest" class="solr.SearchHandler" startup="lazy">
                                                                                                                                                      1307,8        93%

        <requestHandler name="/suggest" class="solr.SearchHandler" startup="lazy">
                 <lst name="defaults">
                         <str name="suggest">true</str>
                         <str name="suggest.dictionary">mySuggester</str>
                         <str name="suggest.build">true</str>
                         <str name="suggest.count">10</str>
                 </lst>
                 <arr name="components">
                        <str>suggest</str>
                 </arr>
        </requestHandler>
<searchComponent name="suggest2" class="solr.SuggestComponent">
          <lst name="suggester">
                 <str name="name">mySuggester2</str>
                 <str name="lookupImpl">FuzzyLookupFactory</str>
                 <str name="dictionaryImpl">DocumentDictionaryFactory</str>
                 <str name="field">suggestion2</str>
                <!-- <str name="weightField">price</str>    -->
                 <str name="suggestAnalyzerFieldType">textSuggest</str>
                 <str name="buildOnStartup">false</str>
         </lst>
        </searchComponent>
        <requestHandler name="/suggest2" class="solr.SearchHandler" startup="lazy">
                 <lst name="defaults">
                         <str name="suggest">true</str>
                         <str name="suggest.dictionary">mySuggester2</str>
                         <str name="suggest.build">true</str>
                         <str name="suggest.count">10</str>
                 </lst>
                 <arr name="components">
                        <str>suggest2</str>
                 </arr>
        </requestHandler>

自增主键uuid的配置:

<requestHandler name="/update" class="solr.UpdateRequestHandler">
     <lst name="defaults">
          <str name="update.chain">dispup</str>
     </lst>
    </requestHandler>

<updateRequestProcessorChain name="dispup">
     <processor class="solr.UUIDUpdateProcessorFactory">
          <str name="fieldName">id</str>
     </processor>
     <processor class="solr.LogUpdateProcessorFactory" />
     <processor class="solr.DistributedUpdateProcessorFactory" />
     <processor class="solr.RunUpdateProcessorFactory" />
</updateRequestProcessorChain>

有了以上的配置就可以实现solr7.1.0的只能提示功能了.
 

这是java代码:

/**
     * 商品搜索关键词智能提示
     *
     * @param keywordSuggestParam
     * @return
     */
    @Override
    public PageInfo<KeywordSuggestResult> keywordSuggest(KeywordSuggestParam keywordSuggestParam) {
        SolrQuery query = new SolrQuery();

        String keyword = keywordSuggestParam.getKeyword();

        if (StringUtils.isBlank(keyword)) {
            keyword = "*";
        }
        if (null != keywordSuggestParam.getType() && keywordSuggestParam.getType() == 1) {
            query.set("qt", "/suggest");
        } else {
            query.set("qt", "/suggest2");
        }
        query.setQuery(keyword);

        solrClient = new HttpSolrClient(solrNoControlMedicineGoods);
        solrClient2 = new HttpSolrClient(solrControlMedicineGoods);
        int isControl1 = 1;
        int isControl2 = 2;
        List<KeywordSuggestResult> keywordSuggestResults = dealKeywordSuggestData(isControl2, solrClient2, keyword, query);
        List<KeywordSuggestResult> keywordSuggestResults1 = dealKeywordSuggestData(isControl1, solrClient, keyword, query);
        if (null != keywordSuggestResults) {
            keywordSuggestResults.addAll(keywordSuggestResults1);
        } else {
            keywordSuggestResults = keywordSuggestResults1;
        }
        PageInfo<KeywordSuggestResult> keywordSuggestResultPageInfo = new PageInfo<>(keywordSuggestResults);
        return keywordSuggestResultPageInfo;

    }


    /**
     * 处理商品搜索关键词提示数据
     *
     * @return
     */
    private List<KeywordSuggestResult> dealKeywordSuggestData(int isControl, SolrClient solrClient, String keyword, SolrQuery query) {
        try {
            List<KeywordSuggestResult> keywordSuggestResultList = new ArrayList<>();
            query.setStart(SEARCH_START);
            query.setRows(SUGGEST_PAGE_SIZE);

            QueryResponse queryResponse = solrClient.query(query);

            GetSuggest(isControl, solrClient, keyword, keywordSuggestResultList, queryResponse);

            return keywordSuggestResultList;
        } catch (SolrServerException e) {
            throw new CustomServiceException(ErrorCodeEnum.DATA_NOT_EXIST.getCode(), ErrorCodeEnum.DATA_NOT_EXIST.getMessage());
        } catch (IOException e) {
            throw new CustomServiceException(ErrorCodeEnum.DATA_NOT_EXIST.getCode(), ErrorCodeEnum.DATA_NOT_EXIST.getMessage());
        }
    }

    private void GetSuggest(int isControl, SolrClient solrClient, String keyword, List<KeywordSuggestResult> keywordSuggestResultList, QueryResponse queryResponse) {
        SuggesterResponse suggest = queryResponse.getSuggesterResponse();
        Map<String, List<Suggestion>> mapSuggestions = suggest.getSuggestions();

        for (Map.Entry<String, List<Suggestion>> entry : mapSuggestions.entrySet()) {
            List<Suggestion> valueList = entry.getValue();
            for (Suggestion suggestion : valueList) {
                String term = suggestion.getTerm();
                if (term.startsWith(keyword)) {
                    KeywordSuggestResult keywordSuggestResult = new KeywordSuggestResult();
                    keywordSuggestResult.setKeyword(keyword);
                    keywordSuggestResult.setSuggestWord(term);
                    keywordSuggestResult.setType(isControl);
                    keywordSuggestResultList.add(keywordSuggestResult);
                }

            }
        }
    }

完成效果:

猜你喜欢

转载自blog.csdn.net/weixin_40910372/article/details/79115419