背景
之前项目中用到了Solr搜索引擎,作为Java程序员,难免要用SolrJ来操作我们的Solr服务器,实现索引的增删改查。
当时公司用的SolrJ版本较老,今天重新看项目源码的时候,在pom.xml更新了jar包版本,发现有一些方法被标注过时,甚至已经被取代(在API中已经不存在了)。
访问Solr官网发布的最新API才明白,SolrJ API发生了一些微妙的变化,虽然这些变化不大,主要就是连接Solr服务器的时候有点区别,但是如果不弄清楚的话,恐怕以后用到的时候报错,心里就该跑过一万只草泥马了……
废话说了这么多,下面直接上代码!
在Spring配置文件声明Bean
需要注意,新版本的SolrJ API,不再使用HttpSolrServer来建立与Solr服务器的连接,而是HttpSolrClient!!!
API推荐的创建连接的方法:
通过在HttpSolrClient的构造函数传入一个其内部类Builder进行构建,需指定一个baseUrl。
具体大家可以看源码,此处就不贴出来了。
因为一般都用IoC容器管理我们的组件,所以这里我们把它声明在Spring配置文件中。当然,你也可以专门写一个管理类来负责创建、关闭连接、提交等等,只要保证在实际应用中前端传过来请求之后,可以正确执行到相关代码就好。
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
<!--配置Solr-->
<bean id="builder" class="org.apache.solr.client.solrj.impl.HttpSolrClient.Builder">
</bean>
<bean id="solr" class="org.apache.solr.client.solrj.impl.HttpSolrClient">
<constructor-arg name="builder" value="builder" />
<property name="baseURL" value="http://localhost:8083/solr/demo_core" />
</bean>
</beans>
后台代码
运行以下代码的前提是,你本地的Solr服务器上有一个demo_core工程(当然这个是灵活的,随便),而且工程里搭配了IK中文分词器,并且配置了索引库字段(不懂的可以查阅网上的资料,也可参考我的第一篇博文)。
package com.wang.money.utils;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.UpdateResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
public class SolrUtil {
private static HttpSolrClient client;
/**
* 由于没有Web环境,所以这里手动加载IoC容器
* */
static {
ApplicationContext context=new ClassPathXmlApplicationContext("application-context.xml");
client=(HttpSolrClient) context.getBean("solr");
}
/**
* 新增或更新文档
* */
@Test
public void save() throws IOException, SolrServerException {
SolrInputDocument document=new SolrInputDocument(); //注意是SolrInputDocument,而非SolrDocument
//可为文档指定id,即addField("id","文档id"),如果id相同则操作为更新。
document.addField("id","123");
document.addField("appName","谁是机械狗");
document.addField("appAPK","com.xxx.xxx");
document.addField("appId",66);
UpdateResponse responseAdd=client.add(document); //这里也不一样,不像以往版本的提交
client.commit(); //提交
System.out.println("save一篇文档成功");
}
/**
* 查询文档
* */
@Test
public void query() throws IOException, SolrServerException {
//声明查询对象,并设置查询条件
SolrQuery query=new SolrQuery();
query.set("q","appName:有没有什么关于机械的玩意");
//执行查询
QueryResponse response=client.query(query);
//获取查询结果,文档集
SolrDocumentList documentList=response.getResults();
for (SolrDocument document:documentList){
System.out.println("查询到的APP名称:"+document.get("appName"));
System.out.println("文档的ID:"+document.get("id"));
System.out.println();
}
}
/**
* 删除文档
* */
@Test
public void delete() throws IOException, SolrServerException {
client.deleteByQuery("appName:删除所有关于机械的文档记录"); //这是根据查询条件删除,也可根据id删除
client.commit();
System.out.println("删除成功");
}
}
接下来开始运行就好,首先插入一条数据,即运行save()方法,然后执行查询,因为我配置了IK中文分词器,并且在appName字段上指定了索引生成规则,所以我的查询条件可以匹配出所有包含“机械”关键字的记录,当然这里只有两条(我后来又添加了一条),你可以自己多save几条进行测试。
然后你再执行删除方法,appName中包含“机械”两个字的文档又都会被删除,再次查询就查不到了。