/**
* 输入框结果自动补全【利用Solr的Select】 PS:后期可以设置权重,排序等规则
* @param map
* @param filterMap
* @param pageSize
* @param sort
* @return
* @throws Exception
*/
public List selectCompletionResult(String suggestionValue, String filterField, String sort) throws Exception{
List proList = new ArrayList<>();
SolrQuery solrQuery = new SolrQuery();
solrQuery.setQuery(Product.SUGGESTION+":"+suggestionValue+"*");
solrQuery.setFields(filterField);
int start = 0 ;
solrQuery.setStart(start); // 设置起始位置
solrQuery.setRows(DEFAULT_PAGESIZE); // 设置页大小
if(sort != null){
solrQuery.setSort("//TODD", ORDER.desc);
}
QueryResponse queryResponse = httpSolrClient.query(solrQuery);
SolrDocumentList solrDocumentList = queryResponse.getResults();
if (!solrDocumentList.isEmpty()) {
Iterator it = solrDocumentList.iterator();
while (it.hasNext()) {
SolrDocument solrDocument = it.next();
Product product = doc2Bean(solrDocument);
proList.add(product);
}
}
return proList;
}
我们可以验证下结果:
List list2 = solrClient.selectCompletionResult("1", Product.COMMODITYNAME, null);
System.out.println(JSON.toJSONString(list2));
<copyField source="commodityName" dest="suggestion" />
<copyField source="id" dest="suggestion" />
solrconfig.xml:
<searchComponent name="suggest" >
<lst name="suggester">
<str name="name">mySuggester</str>
<str name="lookupImpl">FuzzyLookupFactory</str>
<str name="dictionaryImpl">DocumentDictionaryFactory</str>
<str name="field">suggestion</str> <!-- 该字段就是在managed-schema配置的用于suggest模块的字段 -->
<str name="suggestAnalyzerFieldType">string</str>
</lst>
</searchComponent>
<requestHandler name="/suggest" startup="lazy">
<lst name="defaults">
<str name="suggest">true</str>
<str name="suggest.count">10</str> <!-- 这里配置搜索结果数量 -->
</lst>
<arr name="components">
<str>suggest</str>
</arr>
</requestHandler>
二、SolrJ suggest模块
/**
* 输入框结果智能提示【利用Solr的Suggest模块】 PS:后期可以设置权重,排序等规则
*
* ■ It must be fast; there are few things that are more annoying than a clunky type- ahead solution that cannot keep up with users as they type. The Suggester must be able to update the suggestions as the user types each character, so millisec- onds matter.
* ■ It should return ranked suggestions ordered by term frequency, as there is little benefit to suggesting rare terms that occur in only a few documents in your index, especially when the user has typed only a few characters.
* @param suggestionValue
* @param filterField
* @param sort
* @return
* @throws Exception
*/
public List suggestCompletionResult(String suggestionValue, String filterField, String sort) throws Exception {
List suggestWords = new ArrayList();
SolrQuery solrQuery = new SolrQuery();
solrQuery.set("qt", "/suggest");
solrQuery.setParam("suggest.build", true);
solrQuery.setParam("suggest.dictionary", "mySuggester");
solrQuery.setParam("suggest.q", suggestionValue);
solrQuery.setParam("suggest.count", String.valueOf(DEFAULT_PAGESIZE));
if(sort != null){
solrQuery.setSort("//TODD", ORDER.desc);
}
QueryResponse queryResponse = httpSolrClient.query(solrQuery);
SuggesterResponse suggesterResponse = queryResponse.getSuggesterResponse();
Map> suggestMap = suggesterResponse.getSuggestions();
List list = suggestMap.get("mySuggester");
if(list == null || list.size() == 0){
return suggestWords;
}
for (Suggestion suggestion : list) {
suggestWords.add(suggestion.getTerm());
}
return suggestWords;
}
运行下查看效果:
List strings = solrClient.suggestCompletionResult("田", Product.COMMODITYNAME, null);
System.out.println(JSON.toJSONString(strings));
["田1","田2","田3"]
public static final String ID = "id";
public static final String CATEGORYNAME = "cateGoryName";
public static final String BRANDNAME = "brandName";
public static final String COMMODITYNAME = "commodityName";
public static final String COMMODITYIMGURL = "commodityImgUrl";
public static final String SHORTPINYIN = "shortPinYin";
public static final String ALLPINYIN = "allPinYin";
public static final String SUGGESTION = "suggestion";
@Field(ID)
private String id ;
@Field(CATEGORYNAME)
private String cateGoryName;
@Field(BRANDNAME)
private String brandName;
@Field(COMMODITYNAME)
private String commodityName;
@Field(COMMODITYIMGURL)
private String commodityImgUrl;
@Field(SHORTPINYIN)
private String shortPinYin;
@Field(ALLPINYIN)
private String allPinYin;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCateGoryName() {
return cateGoryName;
}
public void setCateGoryName(String cateGoryName) {
this.cateGoryName = cateGoryName;
}
public String getBrandName() {
return brandName;
}
public void setBrandName(String brandName) {
this.brandName = brandName;
}
public String getCommodityName() {
return commodityName;
}
public void setCommodityName(String commodityName) {
this.commodityName = commodityName;
}
public String getCommodityImgUrl() {
return commodityImgUrl;
}
public void setCommodityImgUrl(String commodityImgUrl) {
this.commodityImgUrl = commodityImgUrl;
}
public String getShortPinYin() {
return shortPinYin;
}
public void setShortPinYin(String shortPinYin) {
this.shortPinYin = shortPinYin;
}
public String getAllPinYin() {
return allPinYin;
}
public void setAllPinYin(String allPinYin) {
this.allPinYin = allPinYin;
}
<field name="shortPinYin" type="string" indexed="true" stored="true" multiValued="false" />
<field name="allPinYin" type="string" indexed="true" stored="true" multiValued="false" />
<copyField source="shortPinYin" dest="suggestion" />
<copyField source="allPinYin" dest="suggestion" />
代码实现:
List list2 = solrClient.selectCompletionResult("beijing", Product.COMMODITYNAME, Sort.DESC);
System.out.println(JSON.toJSONString(list2));
PinyinHelper.convertToPinyinString(str, "",PinyinFormat.WITHOUT_TONE); //获取全拼
PinyinHelper.getShortPinyin(str) //获取简拼
相关阅读:用SolrJ操作Solr做搜索(上篇)
本文来自网易实践者社区,经作者田躲躲授权发布。