用SolrJ操作Solr做搜索(下篇)

达芬奇密码2018-07-16 15:43

5、olr实现文字补全功能

很多时候索引数据的时候,例如我们输入:田,搜索引擎就会提示你很多类似的词语,例如:田地等。这里可以用Solr实现汉字补全功能。
/**
	 * 输入框结果自动补全【利用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));
JSON数据:

6、olr实现智能提示

一、配置
这里需要配置两个文件,把需要加入suggest模块的字段配置好。
managed-schema:

   <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"]

7、olr实现拼音补全汉字

一、配置
Product配置:
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;
	}
managed-schema配置:
<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));
结果:
注:在初始化数据时,对需要记性拼音搜索的字段做了拼音处理(用到的框架是JPinyin),具体代码如下:
PinyinHelper.convertToPinyinString(str, "",PinyinFormat.WITHOUT_TONE); //获取全拼

PinyinHelper.getShortPinyin(str) //获取简拼

8、olr其他功能

一、Solr分词
     Solr的分词可以集成第三方比较好用的框架,如 IKAnalyzer、mmseg4j等
二、Solr分布式部署
     Solr的分布式部署要用到Zookeeper框架,SolrJ操作数据用CloudSolrServer类来连接SolrServer
三、Solr相关文档:
   https://en.wikipedia.org/wiki/Apache_Solr
   http://lucene.apache.org/solr/


相关阅读:用SolrJ操作Solr做搜索(上篇)

本文来自网易实践者社区,经作者田躲躲授权发布。