一. solrj简介:
solrj可以使Java应用程序很方便的访问与操作solr。solrj有几个核心类,分别为:1.SolrClient 2.SolrRequests 3.SolrQuerys 4.SolrReponses
tips:该jar包可以在${solr.home}/dist/solrj-lib 找到
gralde配置:
buildscript { ext { springBootVersion = '1.5.8.RELEASE' } repositories { maven { url = "http://maven.aliyun.com/nexus/content/groups/public" } } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") } } apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'org.springframework.boot' group = 'com.bdqn.lyrk.study' version = '0.0.1-SNAPSHOT' sourceCompatibility = 1.8 targetCompatibility = 1.8 repositories { maven { url = "http://maven.aliyun.com/nexus/content/groups/public" } } dependencies { compile('org.springframework.boot:spring-boot-starter-data-solr') compile('org.springframework.boot:spring-boot-starter-web') compileOnly('org.projectlombok:lombok') testCompile('org.springframework.boot:spring-boot-starter-test') }
maven配置:
<dependency> <groupId>org.apache.solr</groupId> <artifactId>solr-solrj</artifactId> <version>x.y.z</version> </dependency>
二 核心类介绍:
1. SolrClient (操作solr的核心类):
由于SolrClient是抽象的,因此要连接solr的远程服务需要创建HttpSolrClient 或者 CloudSolrClient 对象,两者都是以Http请求与solr通信,只不过前者需要一个明确的solr地址信息,后者是基于zookeeper的地址并对solrCloud进行操作,在这里是基于前者的教程
创建代码:
String urlString = "http://localhost:8983/solr/techproducts"; SolrClient solr = new HttpSolrClient.Builder(urlString).build();
solrClient常用方法:
public UpdateResponse add(String collection, SolrInputDocument doc) throws SolrServerException, IOException |
向solr中添加一条数据 参数: collection:在对应的core中添加数据 doc:该参数封装了具体要添加的值 |
public UpdateResponse addBean(String collection,Object obj) throws IOException, SolrServerException |
将对应的bean添加至文档索引当中 |
public UpdateResponse commit(String collection) throws SolrServerException, IOException |
提交本次操作的数据 |
public UpdateResponse rollback(String collection) throws SolrServerException, IOException |
回滚本次操作的数据 |
public UpdateResponse deleteById(String collection, String id) throws SolrServerException, IOException |
根据唯一索引删除索引信息 |
public UpdateResponse deleteByQuery(String collection, String query) throws SolrServerException, IOException |
根据查询删除索引里的文档信息 |
public SolrDocument getById(String id, SolrParams params) throws SolrServerException, IOException |
根据ID进行查询 |
public QueryResponse query(String collection, SolrParams params, METHOD method) throws SolrServerException, IOException |
查询方法 参数: collection:查询的core solrParams:查询参数对象 method:Http请求方式 |
2.SolrDocumentBase
该类是抽象类,并实现Map接口,子类包含SolrDocument和SolrInputDocument。该类主要作用是代表了solr索引中的一条数据信息,对象中的field值必须在magage-schema中定义。通常需要操作solr索引字段时用到SolrInputDoucument
该类常用方法:
void addField(String name, Object value) |
向solr中索引中添加一个Field |
Object getFieldValue(String name) |
根据field获取对应的第一个值或者一组值 |
Collection<String> getFieldNames() |
获取所有的Fields信息 |
3.SolrParams
该类是抽象类,主要用于封装与solr请求时所传的参数信息。该类最常用的子类为SolrQuery, SolrQuery类提供了查询所需的分组,高亮,排序等方法
3.1 SolrInputDocument:
void addField(String name, Object value) |
在索引添加一条Field对应的值 |
void setField(String name, Object value) |
在索引中更新一条Field对应的值 |
3.2 SolrQuery:
ModifiableSolrParams set( String name, String ... val ) |
设置对应的查询参数,具体见下方实例 |
SolrQuery addHighlightField(String f) |
添加高亮显示字段 |
SolrQuery addFilterQuery(String ... fq) |
添加过滤字段 |
SolrQuery addSort(String field, ORDER order) |
添加排序字段 |
4.SolrResponse
该类是抽象类,主要用于solr对用户请求之后做出的响应。
三 简单用例:
实体类:
package com.bdqn.lyrk.study.springboot.entity; import lombok.Data; import org.apache.solr.client.solrj.beans.Field; /** * @author chen.nie */ @Data public class StudentEntity { @Field("id" ) //对应solr中索引的字段 private String id; @Field("userName") private String userName; @Field("classId") private String classId; }
dao对应的实现类:
package com.bdqn.lyrk.study.springboot.dao.solr; import com.bdqn.lyrk.study.springboot.dao.StudentDao; import com.bdqn.lyrk.study.springboot.entity.StudentEntity; import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.client.solrj.response.UpdateResponse; import org.apache.solr.common.SolrInputDocument; import org.apache.solr.common.params.CommonParams; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import org.springframework.util.StringUtils; import java.util.HashMap; import java.util.List; import java.util.Map; /** * dao针对于solr的实现 * @author chen.nie */ @Repository(value = "solrStudentDao") public class SolrStudentDaoImpl implements StudentDao { public static final String COLLECTION = "machines"; @Autowired private SolrClient solrClient; @Override public int save(StudentEntity studentEntity) throws Exception { SolrInputDocument solrInputDocument = new SolrInputDocument(); solrInputDocument.addField("id", studentEntity.getId()); solrInputDocument.addField("userName", studentEntity.getUserName()); solrClient.add(COLLECTION, solrInputDocument); UpdateResponse updateResponse = solrClient.commit(COLLECTION); return updateResponse.getStatus(); } @Override public List<StudentEntity> query(StudentEntity studentEntity) throws Exception { SolrQuery solrQuery = new SolrQuery(); solrQuery.set(CommonParams.Q, "userName:" + studentEntity.getUserName()); QueryResponse queryResponse = solrClient.query(COLLECTION, solrQuery); List<StudentEntity> list = queryResponse.getBeans(StudentEntity.class); return list; } @Override public int update(StudentEntity studentEntity) throws Exception { /* * 注意该类对solr对应字段的原子更新,必须设置对象对应的唯一值 */ SolrInputDocument solrInputDocument = new SolrInputDocument(); solrInputDocument.addField("id", studentEntity.getId()); if (StringUtils.hasLength(studentEntity.getUserName())) { Map<String, Object> map = new HashMap<>(1); map.put("set", studentEntity.getUserName()); solrInputDocument.addField("userName", map); } if (StringUtils.hasLength(studentEntity.getClassId())) { Map<String, Object> map = new HashMap<>(1); map.put("set", studentEntity.getClassId()); solrInputDocument.addField("classId", map); } solrClient.add(COLLECTION, solrInputDocument); UpdateResponse updateResponse = solrClient.commit(COLLECTION); return updateResponse.getStatus(); } }
注意:操作的field必须为存储(store="true"),否则更新的索引会覆盖前面的索引