SolrJ 简述
- SolrJ 是 Solr 官方提供的访问 Solr 服务的 Java 客户端库
- SolrJ 提供增加、修改、删除 和搜索 等各种请求方法,本文先将 添加、修改、删除,查询是重点,单独用一篇来讲,可以参考《Solr 4.10.3 客户端 SolrJ 进行 查询检索 操作》
- SolrJ 通常嵌入在业务系统中,通过 API 接口操作 Solr 服务,如下图:
- 本文会新建项目进行 SolrJ 对 Solr 服务的 CRUD 操作
- 没有安装部署 Solr,或者不熟悉的可以参考《Solr 理论介绍 与 Win10 安装 Solr 4.10.3》、《Lucene_Solr》
环境准备
新建项目
- 以学习 SolrJ API 为主,所以新建 Java SE 项目,不使用 Maven 管理
- 如果要使用 Maven 管理,则可以从 Maven 仓库获取:http://mvnrepository.com/artifact/org.apache.solr
- 新建 class 目录作为应用编译的统一输出目录
- 新建 lib 目录存放开发包
- 所以开发包可以从下载好的 solr 应用中找到,关于 solr 下载可以参考《 Solr 理论介绍 与 Win10 安装 Solr 4.10.3》,下面以 solr 4.10.3 版本为例:
- solr-4.10.3\dist\solr-solrj-4.10.3.jar ——solrJ 核心包
- solr-4.10.3\dist\solrj-lib ——导入整个目录下的依赖包
- solr-4.10.3\example\lib\ext ——导入整个目录下的日志依赖包
Solr 服务端
- Solr 是一个可以运行在 Tomcat 服务器中的全文检索引擎,自己的应用使用 SolrJ 客户端 API 来操作它,所以先要运行 Solr 服务端,不熟悉的可以参考《Solr 理论介绍 与 Win10 安装 Solr 4.10.3》
POJO
- 如同与 Mysql 数据库交互一样,Solr 同样可以看成是一个特殊的数据库,为了数据传输方便,新建一个 POJO 类
package com.wmx.domain;
import java.util.Date;
/**
* Created by Administrator on 2018/9/7 0007.
* 新闻 实体类
*/
public class News {
/**主键 id*/
private Integer id;
/**新闻标题*/
private String title;
/**新闻发布时间*/
private Date publishTime;
/**新闻来源网站名称*/
private String originName;
/**新闻来源网站地址*/
private String originUrl;
/**新闻正文内容*/
private String content;
/**新闻阅读数*/
private Long readNumber;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getOriginName() {
return originName;
}
public void setOriginName(String originName) {
this.originName = originName;
}
public String getOriginUrl() {
return originUrl;
}
public void setOriginUrl(String originUrl) {
this.originUrl = originUrl;
}
public Date getPublishTime() {
return publishTime;
}
public void setPublishTime(Date publishTime) {
this.publishTime = publishTime;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Long getReadNumber() {
return readNumber;
}
public void setReadNumber(Long readNumber) {
this.readNumber = readNumber;
}
@Override
public String toString() {
return "News{" +
"content='" + content + '\'' +
", id=" + id +
", title='" + title + '\'' +
", publishTime=" + publishTime +
", originName='" + originName + '\'' +
", originUrl='" + originUrl + '\'' +
", readNumber=" + readNumber +
'}';
}
}
- Solr 中的域必须 “先定义,后使用” ,所以要有相应的域来对应 POJO 中的属性。
- 不清楚的可以参考《Solr 4.10.3 schema.xml 域类型详解》、《Solr 4.10.3 导入 Mysql 数据》
- 如下所示,除了主键 id 使用 Solr 默认的以为,其余的都是自定义。
<!-- IKAnalyzer-->
<fieldType name="text_ik" class="solr.TextField">
<analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>
<!--IKAnalyzer Field-->
<field name="title_ik" type="text_ik" indexed="true" stored="true" multiValued="true"/>
<field name="content_ik" type="text_ik" indexed="true" stored="true" multiValued="true"/>
<field name="name_ik" type="text_ik" indexed="true" stored="true"/>
<!-- New Entity -->
<field name="news_title" type="text_ik" indexed="true" stored="true"/>
<field name="new_publishTime" type="date" indexed="true" stored="true"/>
<field name="news_originName" type="text_ik" indexed="true" stored="true"/>
<field name="news_originUrl" type="string" indexed="true" stored="true"/>
<field name="news_content" type="text_ik" indexed="true" stored="true"/>
<field name="news_readNumber" type="long" indexed="true" stored="true"/>
<field name="news_text" type="text_ik" indexed="true" stored="false" multiValued="true"/>
<copyField source="news_title" dest="news_text"/>
<copyField source="news_originName" dest="news_text"/>
<copyField source="news_content" dest="news_text"/>
</schema>
SolrJ CRUD
添加/修改索引
- 因为 Solr 底层也是 Lucene ,所以同样没有专门的修改操作,添加与修改操作一致,会自动根据主键域 id 进行判断,如果 id 存在,则删除原来的文档,再添加新文档;如果 id 不存在,则直接添加新文档。
package com.wmx.utils;
import com.wmx.domain.News;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.apache.solr.common.SolrInputDocument;
import java.io.IOException;
import java.util.Date;
/**
* Created by Administrator on 2018/9/7 0007.
* Solr 索引工具类-----管理 索引增加、修改、删除 等操作
*/
public class SolrIndexUtils {
/**
* 添加新闻——文档
*
* @param news :被添加的新闻
*/
public static void addDocument(News news) {
try {
/** 连接 solr 服务端
* HttpSolrServer(String baseURL)
* 1)baseURL:为 Solr 服务端地址,如 http://localhost:8983/solr/SolrCore
* 2)末尾的 SolrCore 未指定时,默认为 collection1
* 3)HttpSolrServer 继承于 org.apache.solr.client.solrj.impl.CloudSolrServer
*/
SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr/collection1");
/** 创建 Solr 文档
* 然后向文档中添加 域及其值
* addField(String name, Object value)
* 1)name:域名,必须在 schema.xml 事先定义好,不存在时会报错
* 2)value:域的值
* 3)主键 id 域 是必须存在的,不存在时报错
* 4)如果 id 已经存在,则删除原来的就文档,再添加此新文档(即修改)
* 5)如果 id 不存在,则直接添加
*/
SolrInputDocument document = new SolrInputDocument();
document.addField("id", news.getId());
document.addField("news_title", news.getTitle());
document.addField("new_publishTime", news.getPublishTime());
document.addField("news_originName", news.getOriginName());
document.addField("news_originUrl", news.getOriginUrl());
document.addField("news_content", news.getContent());
document.addField("news_readNumber", news.getReadNumber());
/** 把 document 添加到索引库中
* 然后提交
* 最后关闭连接,释放资源
*/
solrServer.add(document);
solrServer.commit();
solrServer.shutdown();
} catch (SolrServerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
News news = new News();
news.setId(1001);
news.setTitle("“一带一路”再出发,习近平的这些提法意味深远");
news.setContent("今年是“一带一路”倡议提出五周年。五年前的今天(2013年9月7日),习近平主席出访哈萨克斯坦....");
news.setOriginName("凤凰新闻");
news.setOriginUrl("http://news.ifeng.com/a/20180907/60034084_0.shtml");
news.setPublishTime(new Date());
news.setReadNumber(8888L);
addDocument(news);
}
}
删除索引
- 删除索引 可以通过两种方式操作,一种是通过文档ID进行删除,别一种是通过查询结果进行删除。
根据 id 删除
/**
* 根据 文档id 删除单个 Solr 索引与文档
*
* @param documentId :文档的 主键域 id 值
*/
public static void delDocumentById(String documentId) {
try {
/** 连接 solr 服务端
* HttpSolrServer(String baseURL)
* 1)baseURL:为 Solr 服务端地址,如 http://localhost:8983/solr/SolrCore
* 2)末尾的 SolrCore 未指定时,默认为 collection1
* 3)HttpSolrServer 继承于 org.apache.solr.client.solrj.impl.CloudSolrServer
*/
SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr/collection1");
/**
* deleteById(String id):根据 主键域 id 值删除
* deleteById(List<String> ids):可以同时删除多个
*/
solrServer.deleteById(documentId);
/** 提交
* 最后关闭连接,释放资源
*/
solrServer.commit();
solrServer.shutdown();
} catch (SolrServerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 根据 文档id 列表 删除多个 Solr 索引与文档
* @param documentIds
*/
public static void delDocumentByIds(List<String> documentIds) {
try {
/** 连接 solr 服务端
* HttpSolrServer(String baseURL)
* 1)baseURL:为 Solr 服务端地址,如 http://localhost:8983/solr/SolrCore
* 2)末尾的 SolrCore 未指定时,默认为 collection1
* 3)HttpSolrServer 继承于 org.apache.solr.client.solrj.impl.CloudSolrServer
*/
SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr/collection1");
/** deleteById(String id):根据 主键域 id 值删除
* deleteById(List<String> ids):可以同时删除多个*/
solrServer.deleteById(documentIds);
/** 提交
* 最后关闭连接,释放资源
*/
solrServer.commit();
solrServer.shutdown();
} catch (SolrServerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
delDocumentById("1001");
}
根据查询删除
/**
* 根据 Solr 查询结果进行删除
*
* @param fieldName :域名,如 id、news_title 等, * 表示任意
* @param fieldValue :检索的索引关键字,如 一带一路
*/
public static void delDocumentByQuery(String fieldName, String fieldValue) {
try {
if (fieldName == null || "".equals(fieldName) || fieldValue == null || "".equals(fieldValue)) {
return;
}
/** 连接 solr 服务端
* HttpSolrServer(String baseURL)
* 1)baseURL:为 Solr 服务端地址,如 http://localhost:8983/solr/SolrCore
* 2)末尾的 SolrCore 未指定时,默认为 collection1
* 3)HttpSolrServer 继承于 org.apache.solr.client.solrj.impl.CloudSolrServer
*/
SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr/collection1");
/**
* deleteByQuery(String query):根据查询结果进行删除
* 1)id:1001 ——表示删除 id 为 1001的索引和文档
* 2)news_title:一带一路 ——表示删除标题中含有关键字 "一带一路" 的索引和文档
* 3)*:* 表示删除所有索引 和 文档
*/
solrServer.deleteByQuery(fieldName + ":" + fieldValue);
/** 提交
* 最后关闭连接,释放资源
*/
solrServer.commit();
solrServer.shutdown();
} catch (SolrServerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
delDocumentByQuery("news_title","一带一路");
}
扫描二维码关注公众号,回复:
3079408 查看本文章