<dependencies> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-solr</artifactId> <version>1.5.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.2.4.RELEASE</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.9</version> </dependency> </dependencies>
在src/main/resources下創建 applicationContext-solr.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:solr="http://www.springframework.org/schema/data/solr" xsi:schemaLocation="http://www.springframework.org/schema/data/solr http://www.springframework.org/schema/data/solr/spring-solr-1.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- solr服務器地址 --> <solr:solr-server id="solrServer" url="http://192.168.44.35:8080/solr" /> <!-- solr模板,使用solr模板可對索引庫進行CRUD的操作 --> <bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate"> <constructor-arg ref="solrServer" /> </bean> </beans>
<!-- solr服務器地址 <solr:solr-server id="solrServer" url="http://192.168.44.35:8080/solr" /> --> <bean id="solrServer" class="org.apache.solr.client.solrj.impl.CloudSolrServer"> <constructor-arg value="192.168.25.140:2181,192.168.25.140:2182,192.168.25.140:2183" /> <property name="defaultCollection" value="collection1"></property> </bean>
public class TestBean implements Serializable { // @Field 用來指定那些成員屬性是document的字段的 @Field private String id; @Field("title") private String title; @Field("content") private String content; @Field("name") private String name; //getter and setters }
使用spring data solr執行CURD
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations="classpath:applicationContext-solr.xml") public class TestTemplate { @Autowired private SolrTemplate solrTemplate; //添加 @Test public void testAdd(){ TestBean item=new TestBean(); item.setId("1"); item.setTitle("testTitle"); item.setContent("testContent"); item.setName("testName"); solrTemplate.saveBean(item); solrTemplate.commit(); } //根據id刪除 @Test public void testDelete(){ solrTemplate.deleteById("1"); solrTemplate.commit(); } //分頁查詢 @Test public void testPageQuery(){ Query query=new SimpleQuery("*:*"); query.setOffset(20);//開始索引(默認0) query.setRows(20);//每頁記錄數(默認10) ScoredPage<TestBean> page = solrTemplate.queryForPage(query, TestBean.class); System.out.println("總記錄數:"+page.getTotalElements()); List<TestBean> list = page.getContent(); showList(list); } //顯示記錄數據 private void showList(List<TestBean> list){ for(TestBean item:list){ System.out.println(item.getTitle()); } } //條件查詢 @Test public void testPageQueryMutil(){ Query query=new SimpleQuery("*:*"); Criteria criteria=new Criteria("title").contains("2"); criteria=criteria.and("title").contains("5"); query.addCriteria(criteria); //query.setOffset(20);//開始索引(默認0) //query.setRows(20);//每頁記錄數(默認10) ScoredPage<TestBean> page = solrTemplate.queryForPage(query, TestBean.class); System.out.println("總記錄數:"+page.getTotalElements()); List<TestBean> list = page.getContent(); showList(list); } //刪除全部 @Test public void testDeleteAll(){ Query query=new SimpleQuery("*:*"); solrTemplate.delete(query); solrTemplate.commit(); } }
補充:模擬商品(sku) 查詢 數據存放在solr中 查詢相關條件放到redis做緩存
package com.zy.search.service.impl; import com.alibaba.dubbo.config.annotation.Service; import com.zy.pojo.TbItem; import com.zy.search.service.ItemSearchService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Sort; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.solr.core.SolrTemplate; import org.springframework.data.solr.core.query.*; import org.springframework.data.solr.core.query.result.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @Service public class ItemSearchServiceImpl implements ItemSearchService { @Autowired private SolrTemplate solrTemplate; @Autowired private RedisTemplate redisTemplate; /** * 模擬商品查詢方法 * searchMap格式 {'keywords': '', 'category': '', 'brand': '', 'spec': {},'price': '','pageNo': 1,'pageSize': 20,'sortField':'','sort':''} */ @Override public Map<String, Object> search(Map searchMap) { Map<String, Object> map = new HashMap<>(); //按關鍵字查詢 高亮顯示 map.putAll(searchResultList(searchMap)); //根據關鍵字查詢商品分類 List categoryList = searchCategoryList(searchMap); map.put("categoryList", categoryList); //查詢品牌和規格列表 String categoryName = (String) searchMap.get("category"); if (categoryList == null || !"".equals(categoryName)) {//如果有分類名稱 map.putAll(searchBrandAndSpecList(categoryName)); } else {//如果沒有分類名稱,按照第一個查詢 if (categoryList.size() > 0) { map.putAll(searchBrandAndSpecList((String) categoryList.get(0))); } } return map; } /** * 第二版 篩選過濾后的 帶高亮的數據 */ private Map<String, Object> searchResultList(Map searchMap) { Map<String, Object> map = new HashMap<>(); //***********************關鍵字空格處理*********************** String keywords = (String) searchMap.get("keywords"); searchMap.put("keywords", keywords.replace(" ", "")); HighlightQuery query = new SimpleHighlightQuery(); //***********************按關鍵字查詢*********************** Criteria criteria = new Criteria("item_keywords").is(searchMap.get("keywords")); query.addCriteria(criteria); //---------------------------過濾查詢start--------------------------- //***********************按分類篩選*********************** if (searchMap.get("category") != null && !"".equals(searchMap.get("category"))) { Criteria filterCriteria = new Criteria("item_category").is(searchMap.get("category")); FilterQuery filterQuery = new SimpleFilterQuery(filterCriteria); query.addFilterQuery(filterQuery); } //***********************按品牌篩選*********************** if (searchMap.get("brand") != null && !"".equals(searchMap.get("brand"))) { Criteria filterCriteria = new Criteria("item_brand").is(searchMap.get("brand")); FilterQuery filterQuery = new SimpleFilterQuery(filterCriteria); query.addFilterQuery(filterQuery); } //***********************規格過濾篩選*********************** if (searchMap.get("spec") != null) { Map<String, String> specMap = (Map) searchMap.get("spec"); for (String key : specMap.keySet()) { Criteria filterCriteria = new Criteria("item_spec_" + key).is(specMap.get(key)); FilterQuery filterQuery = new SimpleFilterQuery(filterCriteria); query.addFilterQuery(filterQuery); } } //***********************價格過濾篩選*********************** if (!"".equals(searchMap.get("price"))) { String[] price = ((String) searchMap.get("price")).split("-"); if (!price[0].equals("0")) {//如果區間起點不等於0 Criteria filterCriteria = new Criteria("item_price").greaterThanEqual(price[0]); FilterQuery filterQuery = new SimpleFilterQuery(filterCriteria); query.addFilterQuery(filterQuery); } if (!price[1].equals("*")) {//如果區間終點不等於* Criteria filterCriteria = new Criteria("item_price").lessThanEqual(price[1]); FilterQuery filterQuery = new SimpleFilterQuery(filterCriteria); query.addFilterQuery(filterQuery); } } //---------------------------過濾查詢end--------------------------- //***********************分頁查詢********************** Integer pageNo = (Integer) searchMap.get("pageNo");//提取頁碼 if (pageNo == null) { pageNo = 1;//默認第一頁 } Integer pageSize = (Integer) searchMap.get("pageSize");//每頁記錄數 if (pageSize == null) { pageSize = 20;//默認20 } query.setOffset((pageNo - 1) * pageSize);//從第幾條記錄查詢 query.setRows(pageSize); //***********************排序*********************** String sortValue = (String) searchMap.get("sort");//ASC DESC String sortField = (String) searchMap.get("sortField");//排序字段 if (sortValue != null && !sortValue.equals("")) { if (sortValue.equals("ASC")) { Sort sort = new Sort(Sort.Direction.ASC, "item_" + sortField); query.addSort(sort); } if (sortValue.equals("DESC")) { Sort sort = new Sort(Sort.Direction.DESC, "item_" + sortField); query.addSort(sort); } } //***********************高亮設置*********************** //設置高亮的域 HighlightOptions highlightOptions = new HighlightOptions().addField("item_title"); //高亮前綴 highlightOptions.setSimplePrefix("<em style='color:red'>"); //高亮后綴 highlightOptions.setSimplePostfix("</em>"); //設置高亮選項 query.setHighlightOptions(highlightOptions); //***********************獲取數據*********************** HighlightPage<TbItem> page = solrTemplate.queryForHighlightPage(query, TbItem.class); //***********************設置高亮結果*********************** List<HighlightEntry<TbItem>> highlighted = page.getHighlighted(); for (HighlightEntry<TbItem> h : highlighted) {//循環高亮入口集合 TbItem item = h.getEntity();//獲取原實體類 if (h.getHighlights().size() > 0 && h.getHighlights().get(0).getSnipplets().size() > 0) { item.setTitle(h.getHighlights().get(0).getSnipplets().get(0));//設置高亮的結果 } } //***********************給map賦值*********************** map.put("rows", page.getContent()); map.put("total", page.getTotalElements()); map.put("totalPages", page.getTotalPages()); return map; } /** * 第一版 單純讀取數據 */ private Map<String, Object> searchBase(Map searchMap) { Map<String, Object> map = new HashMap<>(); Query query = new SimpleQuery(); Criteria criteria = new Criteria("item_keywords").is(searchMap.get("keywords")); query.addCriteria(criteria); ScoredPage<TbItem> scoredPage = solrTemplate.queryForPage(query, TbItem.class); List<TbItem> itemList = scoredPage.getContent(); map.put("rows", itemList); map.put("total", scoredPage.getTotalElements()); map.put("totalPages", scoredPage.getTotalPages()); return map; } /** * 查詢品牌和規格列表 */ private Map searchBrandAndSpecList(String category) { Map map = new HashMap(); Long typeId = (Long) redisTemplate.boundHashOps("itemCat").get(category);//獲取模板ID if (typeId != null) { //根據模板ID查詢品牌列表 List brandList = (List) redisTemplate.boundHashOps("brandList").get(typeId); map.put("brandList", brandList);//返回值添加品牌列表 //根據模板ID查詢規格列表 List specList = (List) redisTemplate.boundHashOps("specList").get(typeId); map.put("specList", specList); } return map; } /** * 查詢分類列表 category 根據搜索關鍵字分組查詢 */ private List searchCategoryList(Map searchMap) { List<String> list = new ArrayList(); Query query = new SimpleQuery(); //按照關鍵字查詢 Criteria criteria = new Criteria("item_keywords").is(searchMap.get("keywords")); query.addCriteria(criteria); //設置分組選項 GroupOptions groupOptions = new GroupOptions().addGroupByField("item_category"); query.setGroupOptions(groupOptions); //得到分組頁 GroupPage<TbItem> page = solrTemplate.queryForGroupPage(query, TbItem.class); //根據列得到分組結果集 GroupResult<TbItem> groupResult = page.getGroupResult("item_category"); //得到分組結果入口頁 Page<GroupEntry<TbItem>> groupEntries = groupResult.getGroupEntries(); //得到分組入口集合 List<GroupEntry<TbItem>> content = groupEntries.getContent(); for (GroupEntry<TbItem> entry : content) { list.add(entry.getGroupValue());//將分組結果的名稱封裝到返回值中 } return list; } }
