Solr简介
为什么用Solr#
海量数据下,关系型数据库的搜索效率比较低,最好使用专用搜索工具搜索
常见所搜解决方案#
- 基于Apache Lucene(全文检索工具库)
- 谷歌API
- 百度API
Solr#
- solr基于Apache Lucene构建的用于搜索和分析的开源解决方案
- solr本质是一个内嵌了Jetty服务器的一个Java web项目,请求Solr中控制器,处理完数据后把结果响应给客户端
正向索引和反向索引#
foward index 和 inverted index
正向索引:从文档内容到词组的过程,每次搜索的实收需要搜索所有文档,每个文档i比较搜索条件和词组
反向索引:正向索引的逆向,建立词组和文档的映射关系。通过找到词组就能找到内容
Solr搜索原理#
Solr能够提升检索效率,是因为分词和索引(反向索引)
分词:怼搜索条件/存储内容进行分词,分成日常所使用的词语
索引:存储在solr中内容按照程序员要求建立索引,如果要求建立索引,会把存储内容中关键字存储索引
Solr数据存储说明#
Solr单机安装#
使用git下载7.2版本solr
git clone https://github.com/apache/lucene-solr.git
进入solr目录
cd solr
修改启动参数
cd bin vim solr.in.sh
SOLR_ULIMIT_CHECKS=false
之所以修改这个参数,是因为启动的时候有以下报错
启动solr
./solr start
如果是root账号,会有以下警告
加上force参数
./solr start -force
就像vs code,root账户需要参数 --user-data-dir
可视化管理界面#
新建核心#
Solr安装完成后默认没有核心,需要手动配置
在solr/server/solr下新建文件夹,并给定配置文件,否则无法建立
mkdir testcore
把configsets里面包含的所有配置文件都拷贝到testcore下面
cp -r configsets/_default/conf/ testcore/
填写core信息#
分词Analysis#
在solr可视化管理界面中,有一个Analysis
ik-analyzer#
ik-analyzer是一个中文分词工具包
solr的ik-analyzer官方地址:https://github.com/magese/ik-analyzer-solr#%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E
下载对应的jar包,jar包地址:https://search.maven.org/remotecontent?filepath=com/github/magese/ik-analyzer/8.3.1/ik-analyzer-8.3.1.jar
下载到solr下的webapp/WEB-INF/lib目录中
cd solr/server/solr-webapp/webapp/WEB-INF/lib
然后是使用wget命令
wget https://search.maven.org/remotecontent?filepath=com/github/magese/ik-analyzer/8.3.1/ik-analyzer-8.3.1.jar
修改配置文件
vim solr/server/solr/testcore/conf/managed-schema
vim排版,gg=G
添加下面内容
<field name="myfield" type="text_ik" indexed="true" stored="true" /> <fieldType name="text_ik" 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="true" conf="ik.conf"/> <filter class="solr.LowerCaseFilterFactory"/> </analyzer> </fieldType>
重启#
cd solr/bin ./solr stop -all ./solr start -force
Managed-schema详解#
<fieldType>#
表示定义一个属性类型,在Solr中属性类型都是自定义的
例如name="text_ik"为自定义类型,当某个属性text_ik时,IK Analyzer才能生效
<field/>#
表示向Document中添加一个属性
常用属性
- name,属性名
- type,属性类型
- indexed,是否建立索引
- stored,该属性是否必须,默认id是必须
- multiValued,如果为true,复合属性,包含多个属性,常用多个列作为搜索条件时,
- 把这些列定义成一个新的复合属性,通过搜索一个复合属性实现搜索多个列
- 当设置为true时与<copyField source="" dest=""/>结合使用
<uniqueKey>#
唯一主键,solr中默认定义id属性为唯一主键,ID的值不允许重复
<dynamicField>#
名称中允许*进行通配,代表满足特定名称要求的一组属性
例如
- test_*
Dataimport#
可以使用solr自带的dataimport功能把数据库中数据快速导入到solr中
必须保证managed-schema和数据库中的表的列对应
修改配置文件#
修改solrconfig.xml,添加下面内容
<!-- 配置数据导入的处理器 --> <requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler"> <lst name="defaults"> <!-- 加载data-config.xml --> <str name="config">data-config.xml</str> </lst> </requestHandler>
新建data-config.xml#
和solrconfig.xml同一目录下新建data-config.xml
<?xml version="1.0" encoding="UTF-8"?> <dataConfig> <dataSource type="JdbcDataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://192.168.51.241:3306/maven" user="root" password="root"/> <document> <entity name="product" query="SELECT id,name,price from product"> <field column="id" name="id"/> <field column="name" name="name"/> <field column="price" name="price"/> </entity> </document> </datraConfig>
添加三个jar
- solr-dataimporthandler
- solr-dataimporthandler-extras
- mysql-connector
重启solr,使用可视化界面进行数据导入
菜单项目Documents使用办法#
新增/修改#
<doc> <field name="id">8</field> <field name="name">test</field> <field name="price">98</field> </doc>
删除#
根据主键删除
<delete> <id>8</id> </delete> <commit/>
条件删除
<delete> <query>*:*</query> </delete>
使用solrJ操作Solr#
SolrJ是Solr提供的Java客户端API
添加SolrJ依赖,官方地址:https://mvnrepository.com/artifact/org.apache.solr/solr-solrj
<!-- https://mvnrepository.com/artifact/org.apache.solr/solr-solrj --> <dependency> <groupId>org.apache.solr</groupId> <artifactId>solr-solrj</artifactId> <version>7.7.2</version> </dependency>
新增/修改实现#
String url = "http://192.168.93.10:8983/solr/testcore"; HttpSolrClient solrClient = new HttpSolrClient.Builder(url).build(); SoluInputDocument inputDocument = new SolrInputDocument(); inputDocument.addField("id", "3"); inputDocument.addField("myField", "myfield3"); solrClient.add(inputDocument); solrClient.commit();
添加测试#
public classs SolrTest{ @Test public void testAddAndUpdate(){ String url = "http://192.168.93.10:8983/solr/testcore"; HttpSolrClient httpSolrClient = null; try{ HttpSolrClient httpSolrClient = new HttpSolrClient.Builder(url).build(); SoluInputDocument inputDocument = new SolrInputDocument(); inputDocument.addField("id", "3"); inputDocument.addField("name", "昨天最热手机"); inputDocument.addField("price", "3999"); solrClient.add(inputDocument); solrClient.commit(); }catch(Exception e){ e.printStackTrace(); }finally{ httpSolrClient.close(); } } }
删除实现#
String url = "http://192.168.93.10:8983/solr/testcore"; HttpSolrClient solrClient = new HttpSolrClient.Builder(url).build(); solrClient().commit();
删除测试#
public classs testDelete() throws Exception{ @Test public void testAddAndUpdate(){ String url = "http://192.168.93.10:8983/solr/testcore"; HttpSolrClient httpSolrClient = null; try{ HttpSolrClient httpSolrClient = new HttpSolrClient.Builder(url).build(); HttpSolrClient.deleteById("5"); solrClient.commit(); }catch(Exception e){ e.printStackTrace(); }finally{ httpSolrClient.close(); } } }
查询,排序,分页, 高亮#
public classs testQuery() throws Exception{ @Test public void testAddAndUpdate(){ String url = "http://192.168.93.10:8983/solr/testcore"; HttpSolrClient httpSolrClient = null; try{ HttpSolrClient httpSolrClient = new HttpSolrClient.Builder(url).build(); SolrQuery params = new SolrQuery(); params.setQuery("name:丰富的"); // 排序 params.setSort("price", SolrQuery.ORDER.desc); // 分页 params.setStart(0); params.setRows(1); // 高亮 params.setHighlight(true); params.setHighlightField(“name"); params.setHighlightSimplePre("<span>"); QueryResponse response = solrClient.query(params); SolrDocumentList documents = response.getResults(); System.out.println("总条数:" + documents.getNumFound()); for(SolrDocument doc : documents){ System.out.println(doc.get("id")); System.out.println(doc.get("name")); System.out.println(doc.get("price")); } }catch(Exception e){ e.printStackTrace(); }finally{ httpSolrClient.close(); } } }
Spring Data for Apache Solr#
添加依赖,官方地址:https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
添加依赖,官方地址:https://mvnrepository.com/artifact/org.springframework.data/spring-data-solr
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-solr --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-solr</artifactId> </dependency>
启动类
@SpringBootApplication public class SolrApplication{ public static void main(String[] args){ SpringApplication.run(SolrApplication.class, args); } }
SpringDataSolrTest#
添加一个
@RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = SolrApplication.class) public class SpringDataSolrTest{ @Autowired private SolrTemplate solrTemplate; @Test public void testInsert(){ SolrInputDocument document = new SolrInputDocument(); document.addField("id", "7"); document.addField("name", "phone"); document.addField("price", 2888); solrTemplate.saveDocument("testcore", document); solrTemplate.commit("testcore"); } }
Product
public class Product{ @Field private String id; @Field private String name; @Field private Double price; // getter setter }
添加多个
testInsert2
@Test public void testInsert2(){ Product product = new Product(); product.setId("8"); product.setName("phone"); product.setPrice(2847.1); Product product1 = new Product(); product1.setId("9"); product1.setName("phone1"); product1.setPrice(2857.1); List<Product> list = new ArrayList<>(); list.add(product); list.add(product1); solrTemplate.saveBeans("testcore", list); solrTemplate.commit("testcore"); }
编写配置文件
spring:
data:
solr:
host: http://192.168.93.10:8983/solr
# zk-host: 192.168.9.132:2181, 192.168.9.132:2182, 192.168.9.132:2183
修改#
@Test public void testUpdate(){ SolrInputDocument document = new SolrInputDocument(); document.addField("id", "7"); document.addField("name", "phone123"); document.addField("price", 12888); solrTemplate.saveDocument("testcore", document); solrTemplate.commit("testcore"); }
删除#
@Test public void testDelete(){ solrTemplate.deleteByIds("testcore", 7); solrTemplate.commit("testcore"); }
查询#
@Test public void testQuery(){ SimpleQuery query = new SimpleQuery(); Criteria c = new Criteria(""); criteria.is("phone"); simpleQuery.addCriteria(criteria); ScoredPage<Product> testcore = solrTemplate.queryForPage("testcore", simpleQuery, Product.class); System.out.println(testcore.getContent()); }
SolrCloud#
搭建#
创建
./solr -e cloud -noprompt -force
停止
./solr stop -all
创建
./solr -e cloud -force
重新运行
./solr start -c -p 8983 -s ../example/cloud/node1/solr/ -force ./solr start -c -p 7574 -s ../example/cloud/node2/solr/ -force
作者:BigBender
出处:https://www.cnblogs.com/BigBender/p/14379394.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2020-02-07 B1032. 挖掘机技术哪家强
2020-02-07 B1028. 人口普查
2020-02-07 随机变量的独立性
2020-02-07 二维连续型随机变量概率分布、边缘分布和条件分布
2020-02-07 随机变量函数的分布