Solr是Apache下的一个顶级开源项目,采用Java开发,它是基于Lucene的全文搜索服务器。Solr提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展,并对索引、搜索性能进行了优化,被很多需要搜索的网站中广泛使用。
Solr基于Lucene的Java搜索引擎服务器,其主要功能包括全文检索、命中标示、分面搜索、动态聚类、数据库集成,以及富文本(如Word、PDF)的处理。Solr是高度可扩展的,并提供了分布式搜索和索引复制。
目前使用环境:
我们可在官网下载Solr对应的版本。下载到相应位置并解压,可看到不同的文件目录。
进入到bin目录,打开cmd窗口,运行solr start
即可启动。Solr默认端口为8983,启动成功后可在浏览器访问localhost:8983/solr
,如若启动成功,可看到Solr管理界面。
solr的操作
启动 solr start
停止 solr stop
重启 solr restart
状态 solr status
Solr默认没有中文分词器,作为国人需要自己安装中文分词器,我使用的是IK-Analyzer-Solr8
分词器。可在如下地址下载Jar包。
将下载的Jar包放入到~\solr-8.2.0\server\solr-webapp\webapp\WEB-INF\lib
目录下,并配置~\solr-8.2.0\server\solr\configsets\_default\conf\managed-schema
文件,加入以下配置代码。
在Solr中,每一个Core代表一个索引库,里面包含索引数据及其配置信息。Solr中可以拥有多个Core,也就是同进管理多个索引库、就像MySQL中可以有多个数据库一样。
Solr的bin目录下打开cmd窗口,运行solr create -c test_solr
,test_solr
是core名,可以自定义修改。创建成功后,会在~\solr-8.2.0\server\solr
中出现相应的文件夹,里面需要注意managed-schema、solrconfig.xml两个配置文件。managed-schema定义了索引库的数据类型,同时指明某个类型的字段是不是要进行索引,是不是要进行保存到索引库里等等。solrconfig.xml则是包含了很多solr自身配置相关的参数。
这样我们就可以在Solr界面进行插入Field、插入数据、查询数据等等操作了。
org.apache.solr
solr-solrj
8.2.0
import org.apache.solr.client.solrj.beans.Field;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Worker{
@Field("workid")
private String workid;
@Field("position")
private String position;
@Field("salary")
private double salary;
}
private final static String SOLR_URL = "http://localhost:8983/solr/test_solr2";
HttpSolrClient solr = null;
@Before
public void createSolrServer() {
solr = new HttpSolrClient.Builder(SOLR_URL)
.withConnectionTimeout(10000)
.withSocketTimeout(60000)
.build();
}
1、新增\修改数据
@Test
public void addDoc() throws SolrServerException, IOException {
SolrInputDocument document = new SolrInputDocument();
document.addField("workid", "20190730A82");
document.addField("position", "前端工程师");
document.addField("salary", 8000);
solr.add(document);
solr.commit();
solr.close();
System.out.println("添加成功");
}
2、删除数据
@Test
public void deleteDocById() throws SolrServerException, IOException {
//server.deleteById("39b070b4-c1f6-4f2b-899c-b9f8916ebecc");
solr.deleteByQuery("id:*");
solr.commit();
solr.close();
}
3、查询数据
@Test
public void querySolr() throws Exception {
SolrQuery query = new SolrQuery();
//下面设置solr查询参数
//query.set("q", "*:*");// 参数q 查询所有
//query.set("q", "position:*工程*");//模糊查询
//参数fq, 给query增加过滤查询条件
//query.addFacetQuery("salary:[6000 TO 9000]");
//query.addFilterQuery("position:数据库*"); //
//参数df,给query设置默认搜索域,从哪个字段上查找
query.set("df", "position");
//参数sort,设置返回结果的排序规则
query.setSort("salary",SolrQuery.ORDER.desc);
//设置分页参数
query.setStart(0);
query.setRows(10);
//设置高亮显示以及结果的样式
query.setHighlight(true);
query.addHighlightField("salary");
query.setHighlightSimplePre("");
query.setHighlightSimplePost("");
//执行查询
QueryResponse response = solr.query(query);
//获取实体对象形式
List worker = response.getBeans(Worker.class);
worker.stream().forEach(System.out::println);
//获取返回结果
SolrDocumentList resultList = response.getResults();
System.out.println(FastJsonUtils.toJSONString(resultList));
}
基本查询方式
q 查询的关键字,例如,q=id:1,默认为q=*:*,
fl 指定返回哪些字段,用逗号或空格分隔,注意:字段区分大小写,例如,fl= id,title,sort
start 返回结果的第几条记录开始,一般分页用,默认0开始
rows 指定返回结果最多有多少条记录,默认值为 10,配合start实现分页
sort 排序方式,例如id desc 表示按照 "id" 降序
wt(writer type) 指定输出格式,有 xml, json, php等
fq(filter query) 过虑查询,提供一个可选的筛选器查询。返回在q查询符合结果中同时符合的fq条件的查询结果,
例如:q=id:1&fq=sort:[1 TO 5],找关键字id为1 的,并且sort是1到5之间的。
df 默认的查询字段,一般默认指定。
qt(query type) 指定那个类型来处理查询请求,一般不用指定,默认是standard。
indent 返回的结果是否缩进,默认关闭,用 indent=true|on 开启,一般调试json,php,phps,ruby输出才有必要用这个参数。
version 查询语法的版本,建议不使用它,由服务器指定默认值。
检索运算符
: 指定字段查指定值,如返回所有值*:*
? 表示单个任意字符的通配
* 表示多个任意字符的通配(不能在检索的项开始使用*或者?符号)
~ 表示模糊检索,如检索拼写类似于”roam”的项这样写:roam~将找到形如foam和roams的单词;roam~0.8,检索返回相似度在0.8以上的记录。
AND、||、OR、&& 布尔操作符
NOT、!、- 排除操作符不能单独与项使用构成查询
+ 存在操作符,要求符号”+”后的项必须在文档相应的域中存在
( ) 用于构成子查询
[] 包含范围检索,如检索某时间段记录,包含头尾,date:[201507 TO 201510]
{} 不包含范围检索,如检索某时间段记录,不包含头尾date:{201507 TO 201510}
在进行数据插入之前,一定要提前在managed-schema中定义索引字段、索引字段类型等等参数,不然使用默认类型的时候会出现不是自己想要的类型,然后出现不可预料的问题,建议自己提前定义好再进行数据插入。如果要进行分词搜索,可把相应字段定义text_ik
分词类型(根据中英文或者自定义的分词名)。