Spring Data Solr操作solr的簡單案例


Spring Data Solr簡介

  雖然支持任何編程語言的能力具有很大的市場價值,你可能感興趣的問題是:我如何將Solr的應用集成到Spring中?可以,Spring Data Solr就是為了方便Solr的開發所研制的一個框架,其底層是對SolrJ(官方API)的封裝。

簡單案例:

pom.xml

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

如果連的是solrCloud集群:

    <!-- 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>

 

@Field 注解

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;
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM