通過SpringDataSolr調用Solr

本文是基於下文描述的:
https://blog.csdn.net/weixin_42426099/article/details/105865016

1.環境

  • Solr服務:http://192.168.142.155:8080/solr
  • IDE:Eclipse
  • 項目構建工具:Maven

2.在Solr服務器上添加域

  • 配置solrhome下的schemax.xml文件

    <field name="item_title" type="string" indexed="true" stored="true"/>
    <field name="item_price" type="double" indexed="true" stored="true"/>
    <field name="item_brand" type="string" indexed="true" stored="true"/>
    <dynamicField name="item_spec_*" type="string" indexed="true" stored="true"/>
    <field name="item_cate" type="string" indexed="true" stored="true"/>
    <field name="item_keywords" type="text_ik" indexed="true" stored="false" multiValued="true"/>
    <copyField source="item_title" dest="item_keywords"/>
    <copyField source="item_cate" dest="item_keywords"/>
    <copyField source="item_spec_*" dest="item_keywords"/>
    <copyField source="item_brand" dest="item_keywords"/>
    
    • 域、動態域、複製域
      域field:可以簡單理解爲存放數據的表
      動態域dynamicField:通過通配符,捕獲和索引不完全符合的字段,並定義該字段的域
      複製域copyField:用另一個字段複製的字段填充字段
    • 域的常用屬性
      name:指定域的名稱
      type:指定域的類型
      indexed:是否索引
      stored:是否存儲
      required:是否必須
      multiValued:是否多值
    • 域的類型
      String—>solr.StrField
      在這裏插入圖片描述
      boolean—>solr.BoolField
      int—>solr.TrieIntField
      float—>solr.TrieFloatField
      long—>solr.TrieLongField
      double—>solr.TrieDoubleField
      text_ik—>solr.TextField
  • 此時可在solr控制檯查看配置的域
    在這裏插入圖片描述

3.創建SpringDataSolrMyDemo工程

  • 創建一個Maven工程,工程類型爲jar,工程名爲:SpringDataSolrMyDemo
    在這裏插入圖片描述

  • 引入相關依賴
    pom.xml

    <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>
    
  • 創建Solr的配置文件
    在這裏插入圖片描述
    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:p="http://www.springframework.org/schema/p"
    	xmlns:context="http://www.springframework.org/schema/context"
    	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
    		http://www.springframework.org/schema/context 
    		http://www.springframework.org/schema/context/spring-context.xsd">
    	<!-- solr服務器地址 -->
    	<solr:solr-server id="solrServer" url="http://192.168.142.155:8080/solr" />
    	<!-- solr模板,使用solr模板可對索引庫進行CRUD的操作 -->
    	<bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate">
    		<constructor-arg ref="solrServer" />
    	</bean>
    </beans>
    
  • 創建實體類,註解對應Solr的域

在這裏插入圖片描述

  • ,

    package pojo;
    
    import java.io.Serializable;
    import java.math.BigDecimal;
    import java.util.Map;
    
    import org.apache.solr.client.solrj.beans.Field;
    import org.springframework.data.solr.core.mapping.Dynamic;
    
    public class TbItem  implements Serializable{
    	//Field註解對應相應的域名
    	//主鍵
    	@Field("id")
        private Long id;
    	
    	//標題
    	@Field("item_title")
        private String title;
    	
    	//價格
    	@Field("item_price")
        private BigDecimal price;
        
    
        //品牌
        @Field("item_brand")
        private String brand;
        
        //規格
        @Dynamic
        @Field("item_spec_*")
        private Map<String,String> specMap;
        public Map<String, String> getSpecMap() {
    		return specMap;
    	}
    	public void setSpecMap(Map<String, String> specMap) {
    		this.specMap = specMap;
    	}
        
        //種類
        @Field("item_cate")
        private String category;
        
        public String getCategory() {
            return category;
        }
    
        public void setCategory(String category) {
            this.category = category;
        }
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public String getTitle() {
            return title;
        }
    
        public void setTitle(String title) {
            this.title = title == null ? null : title.trim();
        }
    
      
    
        public BigDecimal getPrice() {
            return price;
        }
    
        public void setPrice(BigDecimal price) {
            this.price = price;
        }
    
    
        public String getBrand() {
            return brand;
        }
    
        public void setBrand(String brand) {
            this.brand = brand == null ? null : brand.trim();
        }
    }
    
  • 創建測試類
    在這裏插入圖片描述

package test;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.Criteria;
import org.springframework.data.solr.core.query.Query;
import org.springframework.data.solr.core.query.SimpleQuery;
import org.springframework.data.solr.core.query.result.ScoredPage;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import pojo.TbItem;



@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:applicationContext-solr.xml")
public class TestTemplate {

	@Autowired
	private SolrTemplate solrTemplate;
	
	//增加(修改)
	@Test
	public void testAdd(){
		TbItem item=new TbItem();
		Map specMap = new HashMap();
		specMap.put("size", "23cm");
		specMap.put("weight", "很重");
		item.setSpecMap(specMap);
		item.setId(1L);
		item.setBrand("小米");
		item.setCategory("手機");
		item.setTitle("小米max");
		item.setPrice(new BigDecimal(2000));		
		solrTemplate.saveBean(item);
		solrTemplate.commit();
	}
	
	//按主鍵查詢
	@Test
	public void testFindOne(){
		TbItem item = solrTemplate.getById(1, TbItem.class);
		System.out.println(item.getTitle());
	}
	
	//按主鍵刪除
	@Test
	public void testDelete(){
		solrTemplate.deleteById("1");
		solrTemplate.commit();
	}
	
	//插入100條測試數據
	@Test
	public void testAddList(){
		List<TbItem> list=new ArrayList();
		for(int i=0;i<100;i++){
			TbItem item=new TbItem();
			item.setId(i+1L);
			item.setBrand("小米");
			item.setCategory("手機");
			item.setTitle("小米max"+i);
			item.setPrice(new BigDecimal(2000+i));	
			list.add(item);
		}
		solrTemplate.saveBeans(list);
		solrTemplate.commit();
	}
	
	//分頁查詢
	@Test
	public void testPageQuery(){
		Query query=new SimpleQuery("*:*");
		query.setOffset(20);//開始索引(默認0)
		query.setRows(20);//每頁記錄數(默認10)
		ScoredPage<TbItem> page = solrTemplate.queryForPage(query, TbItem.class);
		System.out.println("總記錄數:"+page.getTotalElements());
		List<TbItem> list = page.getContent();
		showList(list);
	}	
	//顯示記錄數據
	private void showList(List<TbItem> list){		
		for(TbItem item:list){
			System.out.println(item.getTitle() +" "+item.getPrice());
		}		
	}
	
	//條件查詢
	@Test
	public void testPageQueryMutil(){	
		Query query=new SimpleQuery("*:*");
		Criteria criteria=new Criteria("item_title").contains("米");
		criteria = criteria.and("item_keywords").contains("max8");	
		query.addCriteria(criteria);
		ScoredPage<TbItem> page = solrTemplate.queryForPage(query, TbItem.class);
		System.out.println("總記錄數:"+page.getTotalElements());
		List<TbItem> list = page.getContent();
		showList(list);
	}
	
	//刪除全部數據
	@Test
	public void testDeleteAll(){
		Query query=new SimpleQuery("*:*");
		solrTemplate.delete(query);
		solrTemplate.commit();
	}
}


4.測試調用Solr

  • 新增一條數據
    在這裏插入圖片描述在這裏插入圖片描述
  • 其他功能可自行嘗試

5.問題

  • org.springframework.data.solr.UncategorizedSolrException: ERROR: [doc=1] unknown field ‘item_title’;

    List item
    –原因:Solr服務器上沒有配置對應的域

  • org.springframework.data.solr.UncategorizedSolrException: Document is missing mandatory uniqueKey field: id;

    在這裏插入圖片描述
    –原因:域中定義爲唯一的字段,導入索引庫的時候,該字段沒有值
    在這裏插入圖片描述

  • 關於schema.xml,系統可能存在多個,注意修改的是solrhome目錄下的那個。

  • 修改域後,要使數據生效,需要將數據重新導入到索引庫

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章