• 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
    论读书
    睁开眼,书在面前
    闭上眼,书在心里
  • 相关阅读:
    输入任意个数字求和的小程序
    两个小的java程序,用于练习java基本语法
    《大道至简》第一,二章读后感
    搜索
    Dijkstra模板
    图论
    SPFA模板
    HDU 5114 Collision(扩展欧几里得) xgtao
    BZOJ 1001 狼抓兔子 (最大流转最短路) xgtao
    Codeforces 697C Lorenzo Von Matterhorn(严格二叉树的LCA) xgtao
  • 原文地址:https://www.cnblogs.com/YC-L/p/14379394.html
Copyright © 2020-2023  润新知