Solr基础信息
- 简介
- 基于Apache Lucene(全文检索工具库)构建的用于搜索和分析的开源解决方案。可提供可扩展索引、搜索功能、高亮显示和文字解析功能。
- 本质是java Web项目,内嵌Jetty服务器,所以安装起来非常方便。客户端操作solr的过程和平时我们所写的项目一样,就是请求Solr中的控制器,处理完数据后把结果响应给客户端
- 正向索引和反向索引
- 正向索引,从文档到词组的过程。每次搜索的时候需要搜索所有文档,每个文档比较搜索条件和词组
- 单机版本安装(官网比较详细:https://solr.apache.org/)
- 启动:
- 如果是root用户启动:需要修改solr_in.sh SOLR_ULIMIT_CHECKS=false
- ./solr start (root用户)-force
- collection、core、replica、core
- 由多个cores组成一个逻辑索引叫做一个collection。一个collection本质上是一个可以跨越多个核的索引,同时包含冗余索引。
- collection由不同的shard组成,每个shard又多个replica,每个shard中有一个leadereplica,每个replica是一个物理索引,所以一个replica对应一个core
- 在单节点的solr上,一个core等于一个collection。
- 在solrCloud上,一个collection由分布在不同节点的core组成,但是一个collection仍然为一个逻辑索引,但是这个colletion由不同的core包含不同的shards组成。
- 一个core包含不同封装一个物理索引形成一个实例。
- 一个collection是由分布在不同node上的core组合而成,从而提供一个逻辑索引组成的。
- 一个core主要是一个文档集中text和field的索引。一个solr实例可以包含多个core,每个core根据本地一定的标准互相分开。它去提供结不同的搜索接口给用户,或者提供权限让不同用户有不同权限去访问不同文档。
- collection由一个或者多个shard组成,一个shard包含一个或者多个replica ,一个replica是一个core
单机版安装
字段描述
- fieldType
- 定义一个属性类型,在solr中属性类型都是自定义的。
- field
- 表示向Document中添加一个属性
- 常用的属性:name 属性名 type 类型
- uniqueKey
- 唯一主键,Solr中默认定义id属性为唯一主键。ID的值是不允许重复的
- dynamicField
- 名称中允许*进行通配。代表满足特定名称要求的一组属性
新增数据
在core中的documents中选择update xml
输入:
<doc>
<field name ="id">1</field>
<field name ="zh_all">中华人名共和国国歌</field>
<field name ="zh_smart">中华人名共和国国歌</field>
</doc>
数据导入
需要修改的文件 managed-schema solrconfig.xml
managed-schema
<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
<lst name="defaults">
<str name="config">dataimport.xml</str>
</lst>
</requestHandler>
solrconfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<dataConfig>
<dataSource type="JdbcDataSource"
driver="com.mysql.cj.jdbc.Driver"
url="jdbc:mysql://xxxxxxx:3306/xdclass_product?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8"
user="root"
password="xxxxxx">
</dataSource>
<document>
<entity name="abc" query="select id,title from product">
<field column="id" name="id"></field>
<field column="title" name="zh_all"></field>
</entity>
</document>
</dataConfig>
cp /usr/local/solr/dist/solr-dataimporthandler-* /usr/local/solr/server/solr-webapp/webapp/WEB-INF/lib/
基本安装步骤
#减少启动时的警告信息
cd /usr/local/solr/bin
vi solr.in.sh
SOLR_ULIMIT_CHECKS=false
#启动
./solr start -force
端口8983
#控制台
http://ip:8983
#创建core
cd /usr/local/solr/server/solr
cp configsets/_default/conf/ xxxxx/ -r
#在控制台新增core xxxx
#安装中文的分析器
#以下为maven仓库位置,自行去下载
<dependency>
<groupId>com.github.magese</groupId>
<artifactId>ik-analyzer</artifactId>
<version>8.2.0</version>
</dependency>
将该jar包放置/usr/local/solr/server/solr-webapp/webapp/WEB-INF/lib
然后到需要安装中文分析器的core目录下修改managed-schema文件
在根标记<schema>的第一层开始写
<field name="zh_all" type="text_zh_all" indexed="true" stored="true" />
<field name="zh_smart" type="text_zh_smart" indexed="true" stored="true" />
<fieldType name="text_zh_all" class="solr.TextField">
<analyzer type="index">
<tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="false" conf="ik.conf"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="false" conf="ik.conf"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="text_zh_smart" class="solr.TextField">
<analyzer type="index">
<tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="true" conf="ik.conf"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="true" conf="ik.conf"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
#停止solr
/usr/local/solr/bin/solr stop -all
使用SolrJ操作Solr
依赖:
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>8.2.0</version>
</dependency>
基本操作:
package com.example.solrdemo.solrj;
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.request.UpdateRequest;
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.apache.solr.common.util.NamedList;
import java.io.IOException;
import java.util.Iterator;
public class Test {
public static void main(String[] args) {
query();
}
public static void query(){
HttpSolrClient client = new HttpSolrClient.Builder("http://xxxxxx:8983/solr/xxxx").build();
SolrQuery solrQuery = new SolrQuery();
solrQuery.setSort("id",SolrQuery.ORDER.desc);
solrQuery.setQuery("zh_all:技术");
QueryResponse response;
try {
response = client.query(solrQuery);
System.out.println(response.getResults());
//响应头
NamedList<Object> namedList = response.getHeader();
Iterator iterator = namedList.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
SolrDocumentList documentList = response.getResults();
System.out.println("总计数据行数"+documentList.getNumFound());
for(SolrDocument solrDocument:documentList){
System.out.print("id = "+solrDocument.get("id"));
System.out.println("; zh_all = "+solrDocument.get("zh_all"));
}
//
} catch (SolrServerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void delete(){
HttpSolrClient client = new HttpSolrClient.Builder("http://xxxxxxx:8983/solr/xxxx").build();
try {
client.deleteById("007");
} catch (SolrServerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
try {
client.rollback();
} catch (SolrServerException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
try {
client.commit();
} catch (SolrServerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//包括新增和更新。 主键一致-更新。主键不存在-新增
public static void update(){
HttpSolrClient client = new HttpSolrClient.Builder("http://xxxxx:8983/solr/xxxx").build();
//新增或更新。新增文档类型都是SolrInputDocument
SolrInputDocument doc = new SolrInputDocument();
doc.addField("id","007");
doc.addField("zh_all","测试SolrJ新增数据");
try {
UpdateResponse response = client.add(doc);
System.out.println(String.format("status = %s ; QTime = %s",response.getStatus(),response.getQTime()));
} catch (Exception e) {
e.printStackTrace();
try {
client.rollback();
} catch (SolrServerException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
return ;
}
//在Solr服务中,数据的写操作也是有事务的,WEB管理平台默认一次操作一次提交。
try {
client.commit();
client.close();
} catch (SolrServerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用Spring data Solr
依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-solr</artifactId>
<version>2.3.2.RELEASE</version>
</dependency>
application.properties
#spring data框架定义的访问地址,不能提供索引库定义。
#spring data是直接连接数据源的,可以根据索引库命名访问任意索引库,实现数据访问。
#如果solr是一个集群,则提供zk访问地址。Solr集群称solr cloud,是通过zk搭建的。
spring.data.solr.host=http://xxxx:8983/solr
#spring.data.solr.zk-host=xxx
测试:
@Autowired
private SolrTemplate solrTemplate;
@Test
public void testQuery(){
Criteria criteria = Criteria.where("zh_all").is("技术");
Query query = Query.query(criteria);
ScoredPage<FirstSolrPojo> solrPojos = solrTemplate.queryForPage("bjsxt",query,FirstSolrPojo.class);
System.out.println(solrPojos.getContent());
}
@Test
public void testUpdate(){
// solrTemplate.saveDocument(String collectionName,SolrInputDocument doc);
// solrTemplate.saveDocuments(String collectionName,List<SolrInputDocument> docs);
// solrTemplate.saveBean(String collectionName,Object bean);
// solrTemplate.saveBeans(String collectionName,List<Object> beans);
FirstSolrPojo pojo = new FirstSolrPojo();
pojo.setId("100");
pojo.setZh_all("测试SpringData保存数据1");
FirstSolrPojo pojo1 = new FirstSolrPojo();
pojo1.setId("101");
pojo1.setZh_all("测试SpringData保存数据2");
FirstSolrPojo pojo2 = new FirstSolrPojo();
pojo2.setId("102");
pojo2.setZh_all("测试SpringData保存数据3");
List<FirstSolrPojo> list = new ArrayList<>();
list.add(pojo);
list.add(pojo1);
list.add(pojo2);
solrTemplate.saveBeans("bjsxt",list);
solrTemplate.commit("bjsxt");
}