模糊匹配及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);
}
}
}
}
完成效果: