本文是基於下文描述的:
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’;
–原因:Solr服務器上沒有配置對應的域 -
org.springframework.data.solr.UncategorizedSolrException: Document is missing mandatory uniqueKey field: id;
–原因:域中定義爲唯一的字段,導入索引庫的時候,該字段沒有值
-
關於schema.xml,系統可能存在多個,注意修改的是solrhome目錄下的那個。
-
修改域後,要使數據生效,需要將數據重新導入到索引庫