本文是基于下文描述的:
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目录下的那个。
-
修改域后,要使数据生效,需要将数据重新导入到索引库