ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Solr企业级搜索应用服务器

2022-08-12 10:03:21  阅读:198  来源: 互联网

标签:Solr System 企业级 索引 搜索 query 应用服务器 solr


【Solr:企业级搜索应用服务器】

主要内容

  1. Solr简介
  2. Solr搜索原理
  3. Solr单机版安装
  4. 可视化管理界面
  5. 新建核心
  6. 分词
  7. Dataimport
  8. 使用SolrJ操作Solr
  9. Spring Data for Apache Solr
  10. SolrCloud

一、       Solr简介

1      为什么使用Solr

在海量数据下,对MySQL或Oracle进行模糊查询或条件查询的效率是很低的。而搜索功能在绝大多数项目中都是必须的,如何提升搜索效率是很多互联网项目必须要考虑的问题。

既然使用关系型数据库进行搜索效率比较低,最直接的解决方案就是使用专用搜索工具进行搜索,从而提升搜索效率。

2      常见搜索解决方案

基于Apache Lucene(全文检索工具库)实现搜索。但是Lucene的使用对于绝大多数的程序员都是“噩梦级”的。

基于谷歌API实现搜索。

基于百度API实现搜索。

3      Solr简介

Solr是基于Apache Lucene构建的用于搜索和分析的开源解决方案。可提供可扩展索引、搜索功能、高亮显示和文字解析功能。

Solr本质就是一个Java web 项目,且内嵌了Jetty服务器,所以安装起来非常方便。客户端操作Solr的过程和平时我们所写项目一样,就是请求Solr中控制器,处理完数据后把结果响应给客户端。

4      正向索引和反向索引

只要讨论搜索就不得不提的两个概念:正向索引(forward index)和反向索引(inverted index)。

正向索引:从文档内容到词组的过程。每次搜索的时候需要搜索所有文档,每个文档比较搜索条件和词组。

文档

词组

I am a chinese

I,am,a,chinses

反向索引:是正向索引的逆向。建立词组和文档的映射关系。通过找到词组就能找到文档内容。(和新华字典找字很像)

词组

文档

I,am,a,chinses

I am a chinese

二、       Solr搜索原理

搜索原理

Solr能够提升检索效率的主要原因就是分词和索引(反向索引)。

分词:会对搜索条件/存储内容进行分词,分成日常所使用的词语。

索引:存储在Solr中内容会按照程序员的要求来是否建立索引。如果要求建立索引会把存储内容中关键字(分词)建立索引。

 

 

Solr中数据存储说明

Solr为了给内容建立索引,所以Solr就必须具备数据存储能力。所有需要被搜索的内容都需要存储在Solr中,在开发中需要把数据库中数据添加到Solr中进行初始化,每次修改数据库中数据还需要同步Solr中的数据。

Solr中数据存储是存储在Document对象中,对象中可以包含的属性和属性类型都定义在schema.xml中。如果需要自定义属性或自定义属性类型都需要修改schema.xml配置文件。从Solr5开始schema.xml更改名称为managed-schema(没有扩展名)

 

三、       Solr单机版安装

Solr是使用Java编写,所以必选先安装JDK

1      上传并解压

上传压缩包solr-8.2.0.tgz到/usr/local/tmp中。

解压

# cd /usr/local/tmp

# tar zxf solr-8.2.0.tgz

2      复制到/usr/local中

# cp -r solr-8.2.0 ../solr

3      Solr常用目录简介

 

bin目录:可执行文件所在目录。

dist目录:Solr对外提供的核心、扩展、插件等代码jar文件。

server目录:Solr搜索应用服务器核心目录。

server/solr:Solr的索引库所在位置

server/solr-webapp:Solr的WAR核心应用

server/etc:Solr的核心配置

4      修改启动参数

修改启动参数,否则启动时报警告。提示设置SOLR_ULIMIT_CHECKS=false

# cd /usr/local/solr/bin

# vim solr.in.sh

 

5      启动Solr

Solr内嵌Jetty,直接启动即可。默认监听8983端口。

Solr默认不推荐root账户启动,如果是root账户启动需要添加-force参数。

# ./solr start -force

 

四、       可视化管理界面

在关闭防火墙的前提下,可以在windows的浏览器中访问Solr。

输入: http://127.0.0.1:8983 就可以访问Solr的可视化管理界面。

左侧有5个菜单。分别是:

(1)Dashboard:面板显示Solr的总体信息。

(2)Logging:日志

(3)Core Admin:Solr的核心。类似于数据的Database

(4)Java Perperties:所有Java相关属性。

(5)Thread Dump:线程相关信息。

(6)如果有Core,将显示在此处。

 

五、       新建核心

Solr安装完成后默认是没有核心的。需要手动配置。

需要在solr/server/solr下新建文件夹,并给定配置文件,否则无法建立。

 

1      新建目录

在/usr/local/solr/server/solr中新建自定义名称目录。此处示例名称为testcore。

# cd /usr/local/solr/server/solr

# mkdir testcore

2      复制配置文件

在configsets里面包含了_default和sample_techproducts_configs。里面都是配置文件示例。_default属于默认配置,较纯净。sample_techproducts_configs是带有了一些配置示例。

# cp -r configsets/_default/conf/  testcore/

3      填写Core信息

在可视化管理界面中Core Admin中编写信息后点击Add Core后,短暂延迟后testcore就会创建成功。schema处不用更改。

 

4      出现testcore

在客户端管理界面中,选择新建的Core后,就可以按照自己项目的需求进行操作了。

 

 

六、       分词Analysis

在Solr可视化管理界面中,Core的管理菜单项中都会有Analysis。表示根据Scheme.xml(managed-schema)中配置要求进行解析。

对英文解析就比较简单了,只要按照空格把英文语句拆分成英文单词即可。

 

但是如果条件是中文时,把一句话按照字进行拆分就不是很合理了。正确的方式是按照合理的词组进行拆分。

 

 

1      中文分词器安装及配置步骤

上传ik-analyzer.jar到webapps中。

去https://search.maven.org/search?q=com.github.magese下载对应版本的ik-analyzer。可以在"软件/Analyzer"中直接获取。

1.1    上传jar到指定目录

上传ik-analyzer-8.2.0.jar到

/usr/local/solr/server/solr-webapp/webapp/WEB-INF/lib目录中

1.2    修改配置文件

修改/usr/local/solr/server/solr/testcore/conf/managed-schema

# vim /usr/local/solr/server/solr/testcore/conf/managed-schema

添加下面内容。

排版:Esc 退出编辑状态下: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>

1.3    重启

# cd /usr/local/solr/bin

# ./solr stop -all

# ./solr start -force

1.4    验证

可以在可视化管理界面中找到myfield属性进行验证。

 

2      managed-schema配置说明

2.1    <fieldType/>

表示定义一个属性类型。在Solr中属性类型都是自定义的。在上面配置中name="text_ik"为自定义类型。当某个属性取值为text_ik时IK Analyzer才能生效。

2.2    <field/>

表示向Document中添加一个属性。

常用属性:

name: 属性名

type:属性类型。所有类型都是solr使用<fieldType>配置的

indexed: 是否建立索引

stored: solr是否把该属性值响应给搜索用户。

required:该属性是否是必须的。默认id是必须的。

multiValued:如果为true,表示该属性为复合属性,此属性中包含了多个其他的属性。常用在多个列作为搜索条件时,把这些列定义定义成一个新的复合属性,通过搜索一个复合属性就可以实现搜索多个列。当设置为true时与<copyField source="" dest=""/>结合使用

2.3    <uniqueKey>

唯一主键,Solr中默认定义id属性为唯一主键。ID的值是不允许重复的。

2.4    <dynamicField>

名称中允许*进行通配。代表满足特定名称要求的一组属性。

 

七、       Dataimport

可以使用Solr自带的Dataimport功能把数据库中数据快速导入到solr中.

必须保证managed-schema和数据库中表的列对应。

1      修改配置文件

修改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>

 

2      新建data-config.xml

和solrconfig.xml同一目录下新建data-config.xml

<?xml version="1.0" encoding="UTF-8"?>

<dataConfig>

        <dataSource type="JdbcDataSource"  

                driver="com.mysql.cj.jdbc.Driver"  

                url="jdbc:mysql://192.168.51.241:3306/maven?serverTimezone=Asia/Shanghai"  

                user="root"  

                password="root"/>

        <document>

                <entity name="product" query="SELECT id,name,price from product">

                        <!--

                                                                                                                                                 实现数据库的列和索引库的字段的映射

                 column 指定数据库的列表

                 name  指定索引库的字段名字,必须和schema.xml中定义的一样

                 -->

                 <field column="id" name="id"/>

                 <field column="name" name="name"/>

<field column="price" name="price"/>

         </entity>

 </document>

 

</dataConfig>

 

3      添加jar

向solr-webapp中添加三个jar。在dist中两个还有一个数据库驱动。

 

4      操作

重启solr后,在可视化管理页面中进行数据导入。

注意:

点击导入按钮后,要记得点击刷新按钮。

八、       菜单项目Documents使用办法

以XML格式举例

1      新增/修改

当id不存在时新增,当id存在修改。

<doc>

<field name="id">8</field>

<field name="name">明天更大卖</field>

<field name="price">98</field>

</doc>

2      删除

2.1    根据主键删除

<delete>

<id>8</id>

</delete>

2.2    根据条件删除

<delete>

<query>*:*</query>

</delete>

 

九、       菜单项目query查询使用办法

1      查询全部

只要在q参数中写入*:*既是搜索全部数据。

 

2      条件查询

在q参数部分写入 字段名:搜索条件值, 既是条件搜索

 

3      分页查询

在条件start,rows中输入从第几条数据开始查询,查询多少条数据。下标从0开始。类似MySQL数据库中的limit。

 

4      查询排序

在sort条件中输入 字段名 排序规则。 排序规则包括 asc 和 desc。

 

5      高亮查询

选中hl高亮复选框,在hl.fl中输入高亮显示的字段名称,在hl.simple.pre中输入高亮前缀,在hl.simple.post中输入高亮后缀。

 

十、       使用SolrJ操作Solr

SolrJ是Solr提供的Java客户端API。通过SolrJ可以实现Java程序对Solr中数据的操作。

大前提:添加SolrJ依赖。依赖版本和Solr版本严格对应

<dependencies>
    <dependency>
        <groupId>org.apache.solr</groupId>
        <artifactId>solr-solrj</artifactId>
        <version>8.2.0</version>
    </dependency>
  </dependencies>

 

1      新增/修改实现

 // 包括新增和更新。 主键一致-更新。主键不存在-新增
    public static void update(){
        // basePath,基础访问路径,代表solr服务器所在位置和访问的索引库是什么。
        // 包含:ip, port, 应用名, 索引库名. http://ip:port/solr/索引库名
        String basePath = "http://127.0.0.1:8983/solr/wft";
        // 构造器模式。 建造器模式。
        HttpSolrClient client = new HttpSolrClient.Builder(basePath).build();
        // 访问操作,都是基于客户端的。 就是发送http请求到对应的地址。
        // 新增或更新。 SolrJ定义的标准中,新增的文档类型都是SolrInputDocument。
        SolrInputDocument doc = new SolrInputDocument();
        // SolrInputDocument,就是用于描述一个文档的对象。通过field+value描述一个文档。
        doc.addField("id", "0811001");
        doc.addField("brief", "测试SolrJ更新数据");
        try {
            UpdateResponse response = client.add(doc);
            System.out.println("status = " + response.getStatus());
            System.out.println("QTime = " + response.getQTime());
        } catch (Exception e) {
            e.printStackTrace();
            // 发生异常,可以回滚事务
            try {
                client.rollback();
            } catch (SolrServerException ex) {
                ex.printStackTrace();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            return ;
        }
        // 在Solr服务中,数据的写操作,也是有事务的。 WEB管理平台,默认一次操作一提交。 SolrJ默认回滚。
        // 执行成功,提交事务
        try {
            client.commit();
        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 回收资源。 SolrJ的客户端对象,不需要每次使用后立刻回收。
        // 是基于Http协议的客户端对象,类似浏览器。一次请求,一次应答,连接中断。
        try {
            client.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

  


 

2      删除实现

public static void delete(){
        String basePath = "http://127.0.0.1:8983/solr/wft";
        HttpSolrClient client = new HttpSolrClient.Builder(basePath).build();
        try {
            UpdateResponse response = client.deleteById("0811001");
            System.out.println("==========》"+response.getStatus());
        } catch (Exception e) {
            e.printStackTrace();
            try {
                client.rollback();
            } catch (SolrServerException ex) {
                ex.printStackTrace();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            return;
        }

        try {
            client.commit();
        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

  


 

3      查询实现

public static void query() throws Exception{
        String basePath = "http://127.0.0.1:8983/solr/wft";
        HttpSolrClient client = new HttpSolrClient.Builder(basePath).build();
        // 查询条件对象,就是WEB平台查询页面中左侧的所有可填充内容。
        SolrQuery query = new SolrQuery();
        // 条件可以通过构造方法的构造参数设置,也可以通过方法设置
        query.setQuery("brief:我娃娃可爱不");
        // 排序
        query.setSort("id", SolrQuery.ORDER.desc);
        // 分页
        query.setStart(0);
        query.setRows(10);
        // 开启高亮
        query.setHighlight(true);
        // 设置高亮字段名
        query.addHighlightField("brief");
        // 高亮前缀
        query.setHighlightSimplePre("<span style='color:red'>");
        // 高亮后缀
        query.setHighlightSimplePost("</span>");
        // 查询数据。 响应信息,就是WEB平台查询的返回结果。
        QueryResponse response = client.query(query);
        // 响应头
        NamedList<Object> namedList = response.getHeader();
        Iterator it = namedList.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }

        // 获取所有的高亮结果, key是id,value是map。
        // value map的key是字段名, value是List集合,集合中的数据,是高亮处理后的字段值
        Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();

        // 获取响应体。包括numFound和查询结果集合,start。返回的结果是SolrDocumentList类型的对象。
        // 是List接口的实现,是ArrayList类型的子类。
        SolrDocumentList documentList = response.getResults();
        System.out.println("总计数据行数:"+documentList.getNumFound());
        // SolrDocumentList集合的泛型是SolrDocument。SolrDocument是SolrJ定义中的查询结果文档类型。
        for(SolrDocument doc : documentList){
            Map<String, List<String>> hlrow = highlighting.get(doc.getFieldValue("id"));
            System.out.print("id = " + doc.getFieldValue("id"));
            System.out.print(" ; brief = " + doc.getFieldValue("brief"));
            if(hlrow != null){
                // 有高亮数据,输出
                System.out.print(" ; 高亮结果是 = " + hlrow.get("brief"));
            }
            System.out.println();
        }
    }

  



 

十一、          Spring Data for Apache Solr

1      Spring Data简介

Spring Data 是Spring的顶级项目。里面包含了N多个二级子项目,每个子项目对应一种技术或工具。其目的为了让数据访问更加简单,更加方便的和Spring进行整合。

Spring Data 项目如果单独使用是还需要配置XML配置文件的,当和Spring Boot整合后使用起来非常方便。spring-boot-starter-data-xx就是对应的启动器。

2      实现步骤

2.1    添加依赖

    <dependencies>

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-web</artifactId>

        </dependency>

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-test</artifactId>

        </dependency>

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-data-solr</artifactId>

        </dependency>

    </dependencies>

 

2.2    编写配置文件

spring:

  data:

    solr:

      host: http://192.168.9.132:8080/solr

      # zk-host: 192.168.9.132:2181,192.168.9.132:2182,192.168.9.132:2183

2.3    编写测试类

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = MyApplication.class)
public class MyTest {
    @Autowired
    private SolrTemplate solrTemplate;

    public void testInsert() {
        SolrInputDocument doc = new SolrInputDocument();
        doc.setField("id", "002");
        doc.setField("brief", "我娃娃可爱不");
        UpdateResponse ur = solrTemplate.saveBean("wft", doc);
        if (ur.getStatus() == 0) {
            System.out.println("成功");
        } else {
            System.out.println("失败");
        }
        solrTemplate.commit("collection1");
    }


    public void testDelete() {
        UpdateResponse ur = solrTemplate.deleteByIds("wft", "1");
        if (ur.getStatus() == 0) {
            System.out.println("成功");
        } else {
            System.out.println("失败");
        }
        solrTemplate.commit("wft");
    }
    
    public void query() {
        SimpleQuery query = new SimpleQuery();
        Criteria c = new Criteria("brief");
        c.is("娃娃可爱");
        query.addCriteria(c);
        query.setOffset(1L);
        query.setRows(1);
        ScoredPage<DemoPojo> sp = solrTemplate.queryForPage("wft", query, DemoPojo.class);
        System.out.println(sp.getContent());
    }
    
    @Test
    public void queryHL() {
        List<DemoPojo> listResult = new ArrayList<>();
        SimpleHighlightQuery query = new SimpleHighlightQuery();
        //设置查询条件
        Criteria c = new Criteria("brief");
        c.is("娃娃可爱");
        query.addCriteria(c);
        //分页
        query.setOffset(0L);
        query.setRows(10);
        //排序
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        query.addSort(sort);
        //高亮设置
        HighlightOptions hlo = new HighlightOptions();
        hlo.addField("brief");
        hlo.setSimplePrefix("<span style='color:red;'>");
        hlo.setSimplePostfix("</span>");
        query.setHighlightOptions(hlo);
        HighlightPage<DemoPojo> hl = solrTemplate.queryForHighlightPage("wft", query, DemoPojo.class);
        //        System.out.println(hl.getContent());
        List<HighlightEntry<DemoPojo>> highlighted = hl.getHighlighted();
        for (HighlightEntry<DemoPojo> hle : highlighted) {
            List<HighlightEntry.Highlight> list = hle.getHighlights();
            DemoPojo dp = hle.getEntity();
            for (HighlightEntry.Highlight h : list) {//一个对象里面可能多个属性是高亮属性
                if (h.getField().getName().equals("brief")) {
                    dp.setItem_title(h.getSnipplets().get(0));
                }
            }
            listResult.add(dp);
        }
        System.out.println(listResult);
    }
}

  


十二、          SolrCloud

Solr可以搭建具备容错能力和高可用的Solr集群。集群中集群配置、自动负载均衡和查询故障转移、Zookeeper集群实现集群协调管理,这些全部功能统称为SolrCloud。

SolrCloud是基于Zookeeper进行管理的。在Solr中已经内置了Zookeeper相关内容,当执行集群创建命令会自动创建Zookeeper相关内容。这个使用的是Zookeeper的集群管理功能实现的。

1      搭建

1.1    创建

SolrCloud已经包含在了Solr中,可以直接启动Solr集群。

# ./solr -e cloud -noprompt -force

此命令等同于# ./solr -e cloud -force全部参数为默认值。

运行成功后会在example文件夹多出cloud文件夹。

1.2    停止

# ./solr stop -all

1.3    重新运行

# ./solr start -c -p 8983 -s ../example/cloud/node1/solr/ -force

#./solr start -c -p 7574 -z localhost:9983 -s ../example/cloud/node2/solr/ -force

1.4    增加集群节点

把 "example/cloud/node1/" 目录中的无效数据删除。只保存 node1/solr/目录中的solr.xml和zoo.cfg两个配置文件。其他都文件都删除。目录只保存 node1/ 下的solr和logs两个子目录。

复制node1目录。

cp -r node1/  node2     

cp -r node1/  node3

启动多个Solr节点,搭建SolrCloud集群。

# ./solr start -c -p 8983 -s ../example/cloud/node1/solr/ -force

#./solr start -c -p 7574 -z localhost:9983 -s ../example/cloud/node2/solr/ -force

#./solr start -c -p 6666 -z localhost:9983 -s ../example/cloud/node3/solr/ -force

 

标签:Solr,System,企业级,索引,搜索,query,应用服务器,solr
来源: https://www.cnblogs.com/Payne-SeediqBale/p/16578732.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有