schema.xml配置
Maven工程,POM文件引入jar包:
org.apache.solr solr-solrj 5.5.5
单元测试类:
import java.util.List;
import java.util.Map;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrQuery.ORDER;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.CollectionUtils;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring/mall-context.xml"})
public class SolrTest {
String solrServerUrl="http://192.168.0.210:8080/solr";//solr连接地址
String solrCore="goods_core";//core名称
@Autowired
private IGoodsService goodsService;//商品服务
private HttpSolrClient httpSolrClient;//solr实例对象
/**
* 获取HttpSolrClient实例对象
* @return
*/
private HttpSolrClient getInstance() {
if(httpSolrClient==null) {
httpSolrClient=new HttpSolrClient(solrServerUrl+"/"+solrCore);
httpSolrClient.setDefaultMaxConnectionsPerHost(1000);//每台机器的最大连接数
httpSolrClient.setMaxTotalConnections(10000);//最大连接数
httpSolrClient.setConnectionTimeout(60000);//设置连接超时时间(单位毫秒) 1000
httpSolrClient.setSoTimeout(60000); 设置读数据超时时间(单位毫秒) 1000
httpSolrClient.setFollowRedirects(false);//跟随重定向
httpSolrClient.setAllowCompression(true);//允许压缩
}
return httpSolrClient;
}
@Test
/**
* 添加(更新)多条数据
* @throws Exception
*/
public void saveOrUpdateBatchDocument() throws Exception {
//1、获取HttpSolrClient对象
getInstance();
//2、根据条件获取商品数据集合
List goodsList = goodsService.list(100);
if(!CollectionUtils.isEmpty(goodsList)) {
for(MGoods g:goodsList) {
//3、创建一个文档对象SolrInputDocument对象。
SolrInputDocument document = new SolrInputDocument();
//4、向文档中添加域。必须有id域,域的名称必须在schema.xml中定义。
document.addField("id", g.getId());
document.addField("code", g.getCode());
document.addField("name", g.getName());
document.addField("state", g.getState());
//5、把文档添加到索引库中。
httpSolrClient.add(document);
}
}
//6、提交。
httpSolrClient.commit();
}
@Test
/**
* 添加(更新)单条数据
* @throws Exception
*/
public void saveOrUpdateDocument() throws Exception {
//1、获取HttpSolrClient对象
getInstance();
//2、创建一个文档对象SolrInputDocument对象。
SolrInputDocument document = new SolrInputDocument();
//3、向文档中添加域。必须有id域,域的名称必须在schema.xml中定义。
document.addField("id", 1052);
document.addField("code", "6944839905011");
document.addField("name", "康师傅冰红茶500ml*24瓶2");
document.addField("state", 1);
//4、把文档添加到索引库中。
httpSolrClient.add(document);
//5、提交。
httpSolrClient.commit();
}
@Test
/**
* 根据id删除数据
* @throws Exception
*/
public void deleteDocumentById() throws Exception {
//1、获取HttpSolrClient对象
getInstance();
//2、调用SolrServer对象的根据id删除的方法
httpSolrClient.deleteById("1051");
//httpSolrClient.deleteById(List),根据id集合批量删除
//3、提交。
httpSolrClient.commit();
}
@Test
/**
* 根据查询条件删除数据
* @throws Exception
*/
public void deleteDocumentByQuery() throws Exception {
//1、获取HttpSolrClient对象
getInstance();
//2、删除code=6944839905010的数据
httpSolrClient.deleteByQuery("code:6944839905010");
//3、提交
httpSolrClient.commit();
}
@Test
/**
* 基本查询:写法一(与写法二雷同)
* @throws Exception
*/
public void queryDocument1() throws Exception {
//1、获取HttpSolrClient对象
getInstance();
//2、创建一个SolrQuery对象。
SolrQuery query = new SolrQuery();
//3、向SolrQuery中添加查询条件、过滤条件。。。【查询字段和搜索词一起作为参数,以冒号作为分隔:filed:value】
//query.setQuery("*:*");//查询所有
query.setQuery("name:啤酒");//查询name字段中包含啤酒的
query.setStart(0);//页码从0开始,即第一页
query.setRows(20);//每页显示记录数
query.setSort("id", ORDER.desc);//按照id倒序排列,默认schema.xml中的id为string类型,需要修改为int排序才有效,有意义
//4、执行查询。得到一个Response对象。
QueryResponse response = httpSolrClient.query(query);
//5、取查询结果。
SolrDocumentList solrDocumentList = response.getResults();
System.out.println("查询结果的总记录数:" + solrDocumentList.getNumFound());
//6、遍历结果并打印。
for (SolrDocument solrDocument : solrDocumentList) {
System.out.println(solrDocument.get("id")+"||"+solrDocument.get("code")+"||"+solrDocument.get("name"));
}
}
@Test
/**
* 基本查询:写法二(与写法一雷同)
* @throws Exception
*/
public void queryDocument2() throws Exception {
//1、获取HttpSolrClient对象
getInstance();
//2、创建一个SolrQuery对象。
SolrQuery query = new SolrQuery();
//3、向SolrQuery中添加查询条件、过滤条件。。。【查询字段和搜索词一起作为参数,以冒号作为分隔:filed:value】
//query.setQuery("*:*");//查询所有
query.set("q","name:啤酒");//查询name字段中包含啤酒的数据,带字段查询则默认字段失效[query]
//filter query 过滤查询。使用Filter Query可以充分利用Filter Query Cache,提高检索性能。作用:在q查询符合结果中同时是fq查询符合的(类似求交集),例如:q=mm&fq=date_time:[20081001 TO 20091031],找关键字mm,并且date_time是20081001到20091031之间的。
query.set("fq", "code:6*");//在query的基础上再进行过滤(等同于sql中的and),查询code以6开头的数据[ filter query 过滤查询]
query.set("fq", "name:雪花*");//在query的基础上再进行过滤(等同于sql中的and),查询name以雪花开头[ filter query 过滤查询]
query.set("start",0);//页码从0开始,即第一页
query.set("rows",20);//每页显示记录数
//排序。格式如下:字段名 排序方式
query.set("sort", "id desc");//按照id倒序排列,默认schema.xml中的id为string类型,需要修改为int排序才有效,有意义
//field list。指定查询结果返回哪些字段。多个时以空格“ ”或逗号“,”分隔。不指定时,默认全返回。
query.set("fl", "id,name");//设置返还字段(即select id,name...)[field list]
//4、执行查询。得到一个Response对象。
QueryResponse response = httpSolrClient.query(query);
//5、取查询结果。
SolrDocumentList solrDocumentList = response.getResults();
System.out.println("查询结果的总记录数:" + solrDocumentList.getNumFound());
//6、遍历结果并打印。
for (SolrDocument solrDocument : solrDocumentList) {
System.out.println(solrDocument.get("id")+"||"+solrDocument.get("code")+"||"+solrDocument.get("name"));
}
}
@Test
/**
* 高亮显示:默认字段作为默认搜索字段和默认高亮字段
* @throws Exception
*/
public void queryDocumentWithHighLighting() throws Exception {
//1、获取HttpSolrClient对象
getInstance();
//2、创建一个SolrQuery对象。
SolrQuery query = new SolrQuery();
//3、向SolrQuery中添加查询条件、过滤条件。。。【查询字段和搜索词分别作为参数】
//query.setQuery("啤酒");//查询关键词写法一:等同于下面的写法
query.set("q","啤酒");//查询关键词写法二:等同于上面的写法
//指定默认搜索域(默认字段)
query.set("df", "name");//存在指定默认字段的情况下setQuery或者set(q)可以直接有值,如果setQuery或者set(q)中值的格式为(fild:value),则默认字段失效
//开启高亮显示
query.setHighlight(true);
//指定高亮字段,高亮字段的设置范围仅在setQuery或者set(q)查询字段范围内,如果不设置则会以默认字段作为高亮字段(默认字段必须在查询字段范围内),如果没有默认字段,则没有高亮显示。ID不能设为高亮字段
//query.addHighlightField("name");
//高亮显示的域
query.setHighlightSimplePre("");
query.setHighlightSimplePost("");
//4、执行查询。得到一个Response对象。
QueryResponse response = httpSolrClient.query(query);
//5、取查询结果。
SolrDocumentList solrDocumentList = response.getResults();
System.out.println("查询结果的总记录数:" + solrDocumentList.getNumFound());
//6、遍历结果并打印。
for (SolrDocument solrDocument : solrDocumentList) {
//取高亮显示(key值必须转换为string类型)
Map>> highlighting = response.getHighlighting();
List list = highlighting.get(solrDocument.get("id").toString()).get("name");
String name = null;
if (list != null && list.size() > 0) {
name = list.get(0);
} else {
name = (String) solrDocument.get("name");
}
System.out.println(solrDocument.get("id")+"||"+solrDocument.get("code")+"||"+name);
}
}
@Test
/**
* 高亮显示:显式的设置高亮字段
* @throws Exception
*/
public void queryDocumentWithHighLighting2() throws Exception {
//1、获取HttpSolrClient对象
getInstance();
//2、创建一个SolrQuery对象。
SolrQuery query = new SolrQuery();
//3、向SolrQuery中添加查询条件、过滤条件。。。
query.setQuery("name:啤酒");
//开启高亮显示
query.setHighlight(true);
//指定高亮字段
query.addHighlightField("name");
//高亮显示的域
query.setHighlightSimplePre("");
query.setHighlightSimplePost("");
//4、执行查询。得到一个Response对象。
QueryResponse response = httpSolrClient.query(query);
//5、取查询结果。
SolrDocumentList solrDocumentList = response.getResults();
System.out.println("查询结果的总记录数:" + solrDocumentList.getNumFound());
//6、遍历结果并打印。
for (SolrDocument solrDocument : solrDocumentList) {
//取高亮显示(key值必须转换为string类型)
Map>> highlighting = response.getHighlighting();
List list = highlighting.get(solrDocument.get("id").toString()).get("name");
String name = null;
if (list != null && list.size() > 0) {
name = list.get(0);
} else {
name = (String) solrDocument.get("name");
}
System.out.println(solrDocument.get("id")+"||"+solrDocument.get("code")+"||"+name);
}
}
@Test
/**
* 高亮显示:显式的设置多个高亮字段
* @throws Exception
*/
public void queryDocumentWithHighLighting3() throws Exception {
//1、获取HttpSolrClient对象
getInstance();
//2、创建一个SolrQuery对象。
SolrQuery query = new SolrQuery();
//3、向SolrQuery中添加查询条件、过滤条件。。。
query.setQuery("(code:白熊啤酒) || (name:啤酒)");
//开启高亮显示
query.setHighlight(true);
//指定多个高亮字段,多个用逗号分隔
query.addHighlightField("name,code");
//高亮显示的域
query.setHighlightSimplePre("");
query.setHighlightSimplePost("");
//4、执行查询。得到一个Response对象。
QueryResponse response = httpSolrClient.query(query);
//5、取查询结果。
SolrDocumentList solrDocumentList = response.getResults();
System.out.println("查询结果的总记录数:" + solrDocumentList.getNumFound());
//6、遍历结果并打印。
for (SolrDocument solrDocument : solrDocumentList) {
//取高亮显示(key值必须转换为string类型)
Map>> highlighting = response.getHighlighting();
List list = highlighting.get(solrDocument.get("id").toString()).get("name");
String name = null;
if (list != null && list.size() > 0) {
name = list.get(0);
} else {
name = (String) solrDocument.get("name");
}
List list2 = highlighting.get(solrDocument.get("id").toString()).get("code");
String code = null;
if (list2 != null && list2.size() > 0) {
code = list2.get(0);
} else {
code = (String) solrDocument.get("code");
}
System.out.println(solrDocument.get("id")+"||"+code+"||"+name);
}
}
}
查询注意事项
“:”指定字段查指定值,如返回所有值*:*
“?”表示单个任意字符的通配?
“*” 表示多个任意字符的通配
( ) 用于构成子查询
?[ ] 包含范围检索,如检索某时间段记录,包含头尾,date:[200707 TO 200710]?
?{ }不包含范围检索,如检索某时间段记录,不包含头尾?,date:{200707 TO 200710}
查询某个字段非空的记录 比如:fq=category1Name:['' TO *] 查询FieldName非空的数据。
查询某个字段为空的记录 比如:查询公司名称为空的记录可以采用如下语法实现:fq=-category1Name:['' TO *]