全文搜索技术 Lucene & solr & es (二)Solr(7.7.1)

    xiaoxiao2022-07-13  162

    学习视频地址:https://www.bilibili.com/video/av45567492?from=search&seid=14848044148453483902

    本篇博客是基于此学习视频以及课程笔记进行学习

     

    壹、Solr介绍

    1、什么是solr

    Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口。

    用户可以通过HTTP的POST请求,向Solr服务器提交一定格式的XML或者JSON文件,Solr服务器解析文 件之后,根据具体需求对索引库执行增删改操作;用户可以通过HTTP的GET请求,向Solr服务器发送搜索请求,并得到XML/JSON格式的返回结果。

    Solr 是Apache下的一个顶级开源项目,采用Java开发,基于Lucene。 Solr可以独立运行在Jetty、Tomcat等这些Servlet容器中。 Solr提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展,并对索引、搜索性能进行了优化。 

     

    2、Solr和Lucene的区别

    Lucene是一个开放源代码的全文检索引擎工具包,它不是一个完整的全文检索应用。

    Lucene仅提供了完整的查询引擎和索引引擎,目的是为软件开发人员提供一个简单易用的工具包,以方便的在目 标系统中实现全文检索的功能,或者以Lucene为基础构建全文检索应用。 

    Solr的目标是打造一款企业级的搜索引擎系统,它是基于Lucene一个搜索引擎服务器,可以独立运行,通过Solr可 以非常快速的构建企业的搜索引擎,通过Solr也可以高效的完成站内搜索功能。

     

    贰、Solr安装配置 

    Solr的各个版本下载地址

    http://archive.apache.org/dist/lucene/solr/

    先行声明,如果想要直接在Tomcat中部署直接看Tomcat部署也可以

     

     

     

    默认使用Jetty部署 

    Solr默认提供Jetty(java写的Servlet容器)启动solr服务器。

    使用jetty启动: 1. 进入example目录

    2. 执行命令:java -jar start.jar

    3. 访问地址:http://本机地址:8983/solr

    但是企业中一般使用Tomcat作为服务器,所以下面我们一起来看看如何将solr部署在tomcat中。 

     

    手动部署到Tomcat 

    配置SolrHome 

    1. SolrHome和SolrCore 

    SolrHome是Solr服务器运行的主目录,Solr服务的所有配置信息包括索引库都是在该目录下。

    该目录中包括了多个SolrCore目录。 SolrHome和SolrCore是Solr服务器中最重要的两个目录。 SolrCore就是collection1目录,该目录中包含搜索和索引时需要的配置文件和数据文件(比如索引库中的文件)。 每个SolrCore都可以提供单独的搜索和索引服务。 

     

     

    .2. 创建SolrHome和SolrCore 

    下图中的solr目录就是一个solrhome目录,它就是jetty启动的solr服务使用的solrhome目录。

    复制该文件夹到本地的一个目录,把文件名称改为solrhome。(改名不是必须的,只是为了便于理解)

     

    打开solrhome目录确认是否拥有solrcore

     

    3. 配置SolrCore(了解) 

    其实就是配置SolrCore目录下的conf/solrconfig.xml。

    这个文件是来配置SolrCore实例的相关运行时信息。如果使用默认配置可以不用做任何修改。该配置文件中包含了 不少标签,但是我们经常使用的标签有:lib标签、datadir标签、requestHandler标签

    1) lib 标签 lib标签可以配置扩展功能的一些jar,用以增强solr本身没有的功能。

    比如solr自身没有『数据导入索引库』功能,如果需要使用,则首先要把这些jar复制到指定的目录,然后通过该配 置文件进行相关配置,后面会具体讲解如何配置。  

    2) datadir标签 dataDir数据目录data。data目录用来存放索引文件和tlog日志文件。

    solr.data.dir表示${SolrCore}/data的目录位置

    如果不想使用默认的目录也可以通过solrconfig.xml更改索引目录

    (建议不修改,否则配置多个SolrCore会报错)  

    3)requestHandler标签 

    requestHandler请求处理器,定义了索引和搜索的访问方式。

    通过/update维护索引,可以完成索引的添加、修改、删除操作。

     

    通过/select搜索索引。

    设置搜索参数完成搜索,搜索参数也可以设置一些默认值,如下:

     

    配置IKAnalyzer中文分词器

    第一步:把IKAnalyzer2012FF_u1.jar添加到solr/WEB-INF/lib目录下。

    第二步:复制IKAnalyzer的配置文件和自定义词典和停用词词典到solr的classes目录下。

    第三步:在schema.xml中添加一个自定义的fieldType,使用中文分析器。

     

    Tomcat部署 

    JDK:1.8以上

    Solr:1.7

    Web服务器:tomcat8

     

    安装步骤

    1)单独为solr准备一个服务器(端口8088)(可以不这么做)

    2)找到如下目录内容:

    3)

     

    4)

     

    注释:我使用的solr是7.7版本的,7.7版本里面没有log4j.properties文件,但是有俩个关于log4j的xml文件,我在启动服务的时候在此处报错,然后我重新下载solr7.1版本的在里面有log4jproperties。没有报错

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    没错就是这。

    参考此博客,更为清晰明了

     

    叁、Solr客户端界面介绍

     

    1、Dashboard

    仪表盘,显示了solr实例开始启动运行的时间、版本、系统资源,JVM等

    2、Logging

    显示solr运行出现的异常或错误

    3、Core Admin

    4、java properties

    Solr在JVM运行环境中的属性信息,包括类路径、文件编码、JVM内存设置等信息。可查看到JAVA相关的一些属性的信息

    5、Thread Dump

    显示Solr Server中当前活跃线程信息,同时也可以跟踪线程运行栈信息

    6、Core selector(重点)

    需要在Core Admin里添加了core才有可选项

    1)Analysis (重点)

    通过此界面可以检测索引分析器和搜索分析器的执行情况

    注:solr中,分析器是绑定在域的类型中的

     

    2)dataimport

    可以定义数据导入处理器,从关系数据库将数据导入到Solr索引库中,默认没有配置,需要手工配置

     

    3)Document

    添加数据

    4)Query(重点)

    搜索数据

     

    肆、Solr导入数据

    该功能是数据库中数据通过Sql语句方式导入到Solr索引库中

    1、添加jar包

    solr下的dist下的jar包

    和 mysql的驱动包

    如果用的solr版本大于7,在solr中自带有中文分词器,不需要我们使用第三方中文分词器,并且把相对性的jar包导入到项目的lib目录下,并且需要在schame.xml中进行配置

    赋值到对应项目的lib目录下

     

    二、配置中文分词器

    在solr7版本下配置

    C:\Users\84741\Desktop\ssss\solr\solrhome\demo_core\conf(在timcat的一个core中的conf文件夹中)的  managed-schema中添加

    添加后就可以在solr的界面端使用中文分词器

    schema / managed-schema文件的详解

    1、Field的详解

     

    2、dynamicField详解

     

    3、uniqueKey

    其中的id是在Field标签中已经定义好的域名,而且该域名设置为required为true,一个schema / managed-schema文件中必须有且仅有一个唯一键

     

    4、copyFiled

    复制域

    使用案例:

     

    5、fieldType

    Name:指定域类型的名称

    Class:指定该域类型对应的solr类型

    Analyzer:指定分析器

    Type:index、query 分别指定搜索和索引时的分析器

    Tokenizer:指定分词器

    Filter:指定过滤器

     

    三、修改solrconfig.xml文件

    找到solrhome里面的 core 文件 下的conf里的solrconfig.xml文件,添加dataimport

    首先查询是否存在dataimport的requestHandler,如果不存在,因此需要手动添加,为了以后便于维护此文件,我们就在requestHandler起始位置就处于requestHandler标签所处的区域

     

    四、创建data-config.xml文件

    data-config.xml 作用:数据库连接相关信息,sql以及查询结果映射对应域中

    solrconfig.xml同级目录下,创建data-config.xml文件

    Query代表:查询的sql语句

    Column代表:Sql查询的列名

    Name代表:Solr或Feild的域名

     

    五、客户端查询语句

    q:查询关键字,此参数最为重要,例如q=id:1,  默认为q = *.*.

    单个条件:

    多个条件:

     

    可以参考此博客,学习solr的基本语法

    https://blog.csdn.net/qq_15037231/article/details/79607435

     

    伍、SolrJ的使用

    1、什么是solrj

    SolrJ是操作Solr的java客户端,它提供了增加、修改、删除,查询Solr索引的java接口、Solr针对Solr提供了Rest的Http接口进行了封装,Solr底层是通过HttpClient中的方法来完成Solr的操作的

    2、搭建工程

    搭建Maven工程

     

     

    3、使用Solrj完成索引的维护

    1、java对象绑定

    SolrJ提供了俩个接口  UpdateResponseQueryResponse   他们可以很方便的处理特定域的对象,可以使程序更容易被理解。SolrJ支持通过@Feild注解隐式转换文档和任何类

    每个实例变量在Java对象可以映射在一个相对应的Solr字段中使用field注解

     

    对于Maven构建的项目,pom.xml配置

    solr包的依赖

     

    查看data-config.xml配置

     

     

    2、添加 / 修改索引

    在solr中,索引库中都会存在一个唯一键,如果一个Document的id存在,则执行修改操作,如果不存在,则执行添加操作。

    /** * 在solr中,索引库都会存在一个唯一键 * 如果一个document的id存在,则进行修改操作,如果不存在,则执行添加操作 * @throws IOException * @throws SolrServerException */ @Test public void addOrUpdate() throws Exception{ //请求连接 String baseSolrUrl = "http://localhost:8088/solr/demo_core"; //索引库的url HttpSolrClient client = new HttpSolrClient.Builder(baseSolrUrl).build(); //提供数据 Shop shop = new Shop(); shop.setTsId(111111); shop.setTsInfo("Solr测试-修改"); shop.setTsSellCount(8888); shop.setTsImagepath("asasa"); shop.setTsPrice(88); shop.setTsShopName("田坤至尊店"); shop.setTsAddressSheng("陕西"); shop.setTsAddressShi("西安"); //执行添加成功 UpdateResponse addBean = client.addBean(shop); //事务提交 client.commit(); System.out.println("添加成功"); client.close(); }

     

    3、删除索引

    @Test public void delete() throws Exception { //请求连接 String baseSolrUrl = "http://localhost:8088/solr/demo_core"; //索引库的url HttpSolrClient client = new HttpSolrClient.Builder(baseSolrUrl).build(); //client.deleteById 根据Id作为条件进行删除 //client.deleteById("11111"); //client.deleteByQuery 根据查询结果作为条件进行删除 //client.deleteByQuery("*:*"); //清空Solr索引库 client.deleteByQuery("goods_info:电脑"); //事务提交 client.commit(); System.out.println("删除成功"); client.close(); }

     

     

    4、查询

    1)简单的查询

    /** * 简单的查询 * @throws Exception */ @Test public void select() throws Exception { //请求连接 String baseSolrUrl = "http://localhost:8088/solr/demo_core"; //索引库的url HttpSolrClient client = new HttpSolrClient.Builder(baseSolrUrl).build(); //q:查询关键字 String q = "goods_info:电脑手机"; SolrParams params = new SolrQuery(q); QueryResponse query = client.query(params); List<Shop> list = query.getBeans(Shop.class); System.out.println(list.size()); for (Shop shop : list) { System.out.println(shop); } //事务提交 client.commit(); System.out.println("查询成功"); client.close(); }

     

    因为solr中查询默认是10所以只能查出十条数据

    10 Shop(tsId=1555, tsInfo=华为平板 M5 青春版 10.1英寸智能语音平板电脑4GB+, tsSellCount=1899, tsImagepath=/UpShop/image/uoshoplogo.png, tsPrice=8751.0, tsShopName=你猜我猜不猜呢, tsAddressSheng=陕西, tsAddressShi=西安) Shop(tsId=1551, tsInfo=戴尔DELL游匣G315.6英寸英特尔酷睿i7游戏笔记本电脑, tsSellCount=6699, tsImagepath=/UpShop/image/uoshoplogo.png, tsPrice=8751.0, tsShopName=你猜我猜不猜呢, tsAddressSheng=陕西, tsAddressShi=西安) Shop(tsId=1554, tsInfo=戴尔DELL游匣G3烈焰版 15.6英寸游戏笔记本电脑(i7, tsSellCount=6399, tsImagepath=/UpShop/image/uoshoplogo.png, tsPrice=8751.0, tsShopName=你猜我猜不猜呢, tsAddressSheng=陕西, tsAddressShi=西安) Shop(tsId=1567, tsInfo=华为平板 M5 青春版 10.1英寸智能语音平板电脑4GB+64GB WiFi版(香槟金), tsSellCount=1899, tsImagepath=/UpShop/image/uoshoplogo.png, tsPrice=8751.0, tsShopName=你猜我猜不猜呢, tsAddressSheng=陕西, tsAddressShi=西安) Shop(tsId=1579, tsInfo=华为平板 M5 青春版 10.1英寸智能语音平板电脑4GB+64GB WiFi版(香槟金), tsSellCount=1899, tsImagepath=/UpShop/image/uoshoplogo.png, tsPrice=8751.0, tsShopName=你猜我猜不猜呢, tsAddressSheng=陕西, tsAddressShi=西安) Shop(tsId=1557, tsInfo=荣耀MagicBook 2019 14英寸轻薄窄边框笔记本电脑(AMD锐龙5 3500U 8G 512G FHD IPS 指纹解锁)冰河银, tsSellCount=4049, tsImagepath=/UpShop/image/uoshoplogo.png, tsPrice=8751.0, tsShopName=你猜我猜不猜呢, tsAddressSheng=陕西, tsAddressShi=西安) Shop(tsId=1569, tsInfo=荣耀MagicBook 2019 14英寸轻薄窄边框笔记本电脑(AMD锐龙5 3500U 8G 512G FHD IPS 指纹解锁)冰河银, tsSellCount=4049, tsImagepath=/UpShop/image/uoshoplogo.png, tsPrice=4049.0, tsShopName=你猜我猜不猜呢, tsAddressSheng=陕西, tsAddressShi=西安) Shop(tsId=1560, tsInfo=华为(HUAWEI) MateBook E 2019款 12英寸ACPC全连接轻薄二合一笔记本平板电脑( 钛金灰 高通骁龙850 8G 256G), tsSellCount=3999, tsImagepath=/UpShop/image/uoshoplogo.png, tsPrice=8751.0, tsShopName=你猜我猜不猜呢, tsAddressSheng=陕西, tsAddressShi=西安) Shop(tsId=1572, tsInfo=华为(HUAWEI) MateBook E 2019款 12英寸ACPC全连接轻薄二合一笔记本平板电脑( 钛金灰 高通骁龙850 8G 256G), tsSellCount=3999, tsImagepath=/UpShop/image/uoshoplogo.png, tsPrice=3999.0, tsShopName=你猜我猜不猜呢, tsAddressSheng=陕西, tsAddressShi=西安) Shop(tsId=1559, tsInfo=荣耀MagicBook 英特尔酷睿i7 14英寸轻薄窄边框笔记本电脑(i7-8550U 8G 256G MX150 2G独显 FHD IPS)冰河银, tsSellCount=5399, tsImagepath=/UpShop/image/uoshoplogo.png, tsPrice=8751.0, tsShopName=你猜我猜不猜呢, tsAddressSheng=陕西, tsAddressShi=西安) 查询成功

     

    2)复杂的查询

    /** * SolrJ 查询索引库查询 * 复杂查询 * 模拟电商 * @throws Exception */ @Test public void selectNan() throws Exception { //请求连接 String baseSolrUrl = "http://localhost:8088/solr/demo_core"; //索引库的url HttpSolrClient client = new HttpSolrClient.Builder(baseSolrUrl).build(); //查询的条件 SolrQuery query = new SolrQuery(); //查询关键字 String keyword ="电脑手机"; //1、设置q ————> 主页检索出入框 //判断用户是否对keyword赋值 if(StringUtils.isEmpty(keyword)) { //如果用户没有对keyword进行辅助,查询所有的商品 keyword = "*"; query.set("q",keyword); }else { //如果用输入关键字,进行字符串拼接 query.set("q",keyword); } //2、设置fq //2。1、类别筛选 String goods_addressSheng ="陕西"; //ps:因为我的数据库中没有类别这个数据,所以以省地址来模拟类别操作 if(!StringUtils.isEmpty(goods_addressSheng)){ //如果为空不设置,如果选择了加入查询条件 query.addFilterQuery("goods_addressSheng:"+goods_addressSheng); } //2.2、价格筛选 String goods_price =""; if(!StringUtils.isEmpty(goods_price)) { String[] split = goods_price.split("-"); if(split.length == 1) { query.addFilterQuery("goods_price:"+"["+split[0]+" TO *]"); }else { String pre = split[0]; if(StringUtils.isEmpty(split[0])) { pre = "*"; } query.addFilterQuery("goods_price:["+pre+" TO "+split[1]+"]"); } } //3、排序功能 //sort 1 = 升序 2 = 降序 int sort = 1; if(sort == 1) { query.addSort("goods_price", ORDER.asc); }else if(sort == 2) { query.addSort("goods_price", ORDER.desc); } //4、设置分页功能 /** * mysql 分页语法相似 * start offset 偏移量 * rows rows 返回最大的记录数 */ query.setStart(0); query.setRows(20); //5、设置回显 作用:保护隐私数据 query.setFields("id","goods_info","goods_price"); //6、设置默认域 query.set("df", "goods_info"); //7、高亮设置 //开启高亮功能 query.setHighlight(true); //设置需要加高亮的字段 query.addHighlightField("goods_info"); query.setHighlightSimplePre("<font color='red'>"); query.setHighlightSimplePost("</font>"); QueryResponse queryResponse = client.query(query); List<Shop> list = queryResponse.getBeans(Shop.class); System.out.println(list.size()); //获取到高亮数据 Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting(); for (Shop shop : list) { String tsId = shop.getTsId(); Map<String, List<String>> hinfo = highlighting.get(tsId); List<String> list2 = hinfo.get("goods_info"); //如果用户关键字搜索不为空则可以显示出高亮,反之则无 if(list2 != null) { System.out.println(list2.get(0)+" "+shop.getTsPrice()); }else { System.out.println(shop.getTsInfo()+" "+shop.getTsPrice()); } } //事务提交 client.commit(); System.out.println("查询成功"); client.close(); }

     

    ps:以上只是对于索引库的修改,用户实验,而真正则是要数据库和索引库同时修改

     

     

     

     

     

     

     

     

     

    最新回复(0)