solr整理

来源:互联网 发布:go web编程 编辑:程序博客网 时间:2024/06/07 10:50

solr介绍

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

lucene和solr区别

Lucene是一个开放源代码的全文检索引擎工具包,它不是一个完整的全文检索应用。Lucene仅提供了完整的查询引擎和索引引擎,目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者以Lucene为基础构建全文检索应用。
Solr的目标是打造一款企业级的搜索引擎系统,它是基于Lucene一个搜索引擎服务,可以独立运行,通过Solr可以非常快速的构建企业的搜索引擎,通过Solr也可以高效的完成站内搜索功能。

lucene:直接调用api查询
solr:
1. solr是一个web服务
2. solr部署tomcat服务器
3. 通过语句维护

solr安装与运行

1)加载start.jar启动包
2)加载jetty服务器启动容器(类似于tomcat容器)
3)加载webapps下面solr服务程序(solr.war)
4)加载solr服务器程序索引仓库

访问:http://localhost:8983/solr/

solr运行在tomcat中

solr部署步骤:
1. 把solr.war拷贝tomcat服务器 tomcat/webapps
2. 解压solr.war,直接运行tomcat,自动解压
3. 拷贝solr依赖jar文件
- solr内置日志文件:solr解压包/example/lib/ext/* -> tomcat/webapps/solr/WEB-INF/lib/
- contrib,dist依赖类库:solr解压包/ -> 自定义solr仓库/ ====修改solrConfig.xml加载依赖类库
4. 创建自定义仓库
* solr是一个web项目,部署tomcat服务器中运行web项目
* solr用来做搜索,搜索索引库,需要索引仓库
* 在F/:solr定义索引仓库
5. 指定solr服务索引仓库位置
* 配置tomcat/bin/catalina.bat
* set JAVA_OPTS = “-Dsolr.solr.home=F:/solr”

管理界面功能介绍

  1. Dashboard
    仪表盘,显示了该Solr实例开始启动运行的时间、版本、系统资源、jvm等信息。
  2. Logging
    Solr运行日志信息
  3. Cloud
    Cloud即SolrCloud,即Solr云(集群),当使用Solr Cloud模式运行时会显示此菜单,该部分功能在第二个项目,即电商项目会演示。
  4. Core Admin
    Solr Core的管理界面。在这里可以添加SolrCore实例(有bug,不推荐使用浏览器界面添加SolrCore)。
  5. java properties
    Solr在JVM 运行环境中的属性信息,包括类路径、文件编码、jvm内存设置等信息。
  6. Tread Dump
    显示Solr Server中当前活跃线程信息,同时也可以跟踪线程运行栈信息。
  7. Core selector
    选择一个SolrCore进行详细操作,如下:

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

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

    • 7.3 Document
      通过/update表示更新索引,solr默认根据id(唯一约束)域来更新Document的内容,如果根据id值搜索不到id域则会执行添加操作,如果找到则更新。

通过此菜单可以创建索引、更新索引、删除索引等操作,

  • overwrite=”true” : solr在做索引的时候,如果文档已经存在,就用xml中的文档进行替换
  • commitWithin=”1000” : solr 在做索引的时候,每隔1000(1秒)毫秒,做一次文档提交。为了方便测试也可以在Document中立即提交,后添加“”

    • 7.4 Query
      通过/select执行搜索索引,必须指定“q”查询条件方可搜索。

solr home的目录结构

solr home顾名思义,就是solr的家,即solr的存放数据的仓库(索引库)。每个solr home下可以有多个solr core,这个就是用来存放索引的地方。
solr home ——–> 对应 数据库
solr core ——–> 对应 数据库下的表

solr core

core.properties,用来指定solr core(索引库)的名称

conf配置文件

  • schema.xml,域(类似数据库字段),域类型(字段类型),动态域(类似数据库字段),复制域(类似数据库字段)

    1. field节点
      作用:配置索引的字段,该节点具有以下常用属性:
      • name:代表数据字段名称
      • type:代表数据类型
      • indexed:true or false,代表是否被创建索引
      • stored:true or false,代表是否被存储
      • multivalued:是否是多值,存储多个值时设置为true,比如存储一个用户的好友id(多个),商品的图片(多个,大图和小图)。
    2. dynamicField
      作用:动态的检索字段。
    3. uniqueKey
      作用:相当于数据库主键
    4. copyField
      作用:将多个字段的值复制到同一个目标字段中。检索时可以根据指定的dest的字段检索。
      • source:源字段
      • dest:目标字段
    5. fieldType
      作用:指定索引字段的类型。具有如下常见属性:
      • name:索引字段的类型名,并filed节点中的name引用
      • class:代表solr的类型
      • analyzer:指定分词器,type=index/query,index:创建索引;
      • query:查询索引
      • tokenizer:指定分词器
      • filter:指定过滤器
  • solrconfig.xml核心配置文件,solr服务一一对应,solr服务请求执行,对应solrConfig配置文件当中执行类
    作用:定义了solr服务的一些处理规则,包括索引数据的存放位置;更新、删除、查询的一些规则配置。常用的节点有:

    • luceneMatchVersion:指定底层使用的Lucene版本号
    • lib:指定solr服务运行需要的jar
    • dataDir:指定索引的存放位置
    • requestHandler:配置solr CRUD的规则

自定义索引库

  1. copy solr的模板collection1
  2. 修改索引库名称
  3. 修改solrConfig
  4. 修改schema.xml文件

使用IK分词器 ###

安装分词器:
1. 导入jar包
* 把IK分词器jar文件放入tomcat/webapps/solr/WEB-INF/lib
2. 导入IK分词器配置文件
* 把IK分词器配置文件IKAnalyzer.cfg.xml,ext.dic.stopword.dic拷贝 tomcat/webapps/solr/WEB-INF/classes(自己创建)

  1. 域类型–使用IK分词器

    • 在conf的schema.xml中配置域类型

      <!-- IKAnalyzer--><fieldType name="text_ik" class="solr.TextField">  <analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>

  2. 域使用IK分词器

    • 域使用IK分词器

      <!--IKAnalyzer Field--><field name="content_ik" type="text_ik" indexed="true" stored="true" /> 

在索引库必须存在和数据库字段相对应域,然后把数据库字段所对应值添加,域名称和字段名称没必要相同.
加载jar包

solrj对索引库的维护

solrj是通过Java客户端去操作solr,它提供了一个Java接口用于添加、更新和查询solr的索引.

  1. 创建工程
  2. 准备环境
  3. 索引的维护

添加索引

        /**         * 连接远程solr服务,添加/修改索引库索引         * @throws Exception          * @throws SolrServerException          */        @Test        public void addIndexSolr() throws Exception{            //指定远程solr服务地址            String solrUrl = "http://localhost:8080/solr/article";            //创建solrj核心对象            SolrServer solrServer = new HttpSolrServer(solrUrl);            //创建文档对象            SolrInputDocument document = new SolrInputDocument();            //向索引库引域添加索引值,此索引域必须在索引库中存在            document.addField("id", "p101");            document.addField("title", "solr经典教程,适合初学者");            document.addField("content", "solr功能很强大!");            //添加索引库            solrServer.add(document);            //提交            solrServer.commit();        }

更新索引

如果id相同,则执行更新操作。

删除索引

  1. 根据id删除
  2. 先查在删
        /**         * 删除索引库         * @throws Exception          * @throws           */        @Test        public void deleteIndexSolr() throws Exception{            //指定远程solr服务器地址            String solrUrl = "http://localhost:8080/solr/article";            //连接远程服务器            SolrServer solrServer = new HttpSolrServer(solrUrl);            //第一种删除方式:根据id进行删除    //      solrServer.deleteById("p101");            //第二种删除方式:根据查询删除索引库索引            solrServer.deleteByQuery("id:p101");            //提交            solrServer.commit();        }

查询索引

  1. q:query(主查询条件)
  2. fq:filter query 过滤查询,必须在q主查询条件有值时才能进行过滤
  3. sort排序 语法: 排序字段 desc / asc
  4. filter field 过滤字段 select name,price from products
    solr:过滤域字段 字段之间是有空格或者,都可.
  5. default 设置默认查询字段,一般默认查询字段设置复制域
  6. hl.fl 设置高亮 hl.simple.fl 设置高亮前缀
        /**         * 使用solr复杂查询         * @throws Exception          */        @Test        public void queryIndexBySolr() throws Exception{            //指定远程solr服务地址            String url = "http://127.0.0.1:8080/solr/products";            //创建solr服务对象,连接远程solr服务对象            SolrServer solrServer = new HttpSolrServer(url);            //solr提供参数封装类,封装查询语法,封装参数            SolrQuery solrQuery = new SolrQuery();            //查询所有    //      solrQuery.set("q", "*:*");            //a.q主条件查询            solrQuery.setQuery("婚庆");            //b.fq过滤查询,必须在q主查询条件有值时候才能进行过滤            solrQuery.addFilterQuery("product_price:[20 TO *]");            //使用solr服务查询            QueryResponse response = solrServer.query(solrQuery);            //c.sort排序查询            //参数1:设置需要查询字段名称            //参数2:设置排序方式 desc asc            solrQuery.setSort("product_price", ORDER.desc);            //d.设置分页            solrQuery.setStart(0);            solrQuery.setRows(10);            //e.fl:字段过滤查询,查询需要字段即可,域字段之间使用空格或者逗号分割    //      solrQuery.setFields("product_price,product_name");    //      solrQuery.addField("product_price,product_name");            //f.高亮显示            //开启高亮显示            solrQuery.setHighlight(true);            //指定高亮显示字段,高亮显示字段不能是复制域,只能是单个域            solrQuery.addHighlightField("product_name");            //设置高亮前缀            solrQuery.setHighlightSimplePre("<font color='red'>");            //设置高亮后缀            solrQuery.setHighlightSimplePost("</font>");            //获取查询列表集合对象            SolrDocumentList solrDocumentList = response.getResults();            //获取命中总记录数            long numFound = solrDocumentList.getNumFound();            System.out.println(numFound);            //获取文档数据            for (SolrDocument solrDocument : solrDocumentList) {                //获取文档数据                String id = (String) solrDocument.get("id");                System.out.println("商品id:"+id);                String product_name = (String) solrDocument.get("product_name");                //获取高亮                Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();                //第一个map的key就是高亮文档的id                Map<String, List<String>> map = highlighting.get(id);                //第二个map的key就是高亮字段域名称                List<String> list = map.get("product_name");                //判断高亮是否存在                if (list != null && list.size() > 0) {                    product_name = list.get(0);                }                System.out.println("商品名称:"+product_name);                Float product_price = (Float) solrDocument.get("product_price");                System.out.println("商品价格:"+product_price);                String product_description = (String) solrDocument.get("product_description");                System.out.println("商品扫描:"+product_description);                String product_picture = (String) solrDocument.get("product_picture");                System.out.println("商品图片:"+product_picture);                String product_catalog_name = (String) solrDocument.get("product_catalog_name");                System.out.println("商品种类名称:"+product_catalog_name);                String product_keywords = (String) solrDocument.get("product_keywords");                System.out.println("商品关键字:"+product_keywords);            }        }

案例

环境搭建:
1. jar
* 加载springmvc配置文件:spring
* 查询远程solr索引库
2. 配置文件
* psringmvc
* solrJ交给spring管理
3. JD案例页面
4. web.xml
* 编码过滤器
* 配置springmvc.xml

5. 将数据库数据导入索引库

5.1 添加DataImportjar包
复制dist目录中的solr-dataimporthandler-4.10.3.jar
没有lib目录,需要手动创建(可以不放lib文件夹中,后面的配置文件路径匹配即可)
5.2 添加数据库驱动包
5.3 修改配置文件,加载jar包,
5.4 配置requestHandler
在solrconfig.xml配置文件中添加:

        <requestHandler name="/dataimport"           class="org.apache.solr.handler.dataimport.DataImportHandler">        <lst name="defaults">          <str name="config">data-config.xml</str>         </lst>        </requestHandler> 

5.5 创建data-config.xml配置文件
在collection1\conf\目录下创建data-config.xml文件

    <?xml version="1.0" encoding="UTF-8" ?>      <dataConfig>       <dataSource type="JdbcDataSource"                 driver="com.mysql.jdbc.Driver"                 url="jdbc:mysql://127.0.0.1:3306/solr"                 user="root"                 password="root"/>       <document>           <entity name="product" query="SELECT pid,name,catalog,catalog_name,price,description,picture FROM products">             <field column="pid" name="id"/>              <field column="name" name="product_name"/>              <field column="catalog" name="product_catalog"/>             <field column="catalog_name" name="product_catalog_name"/>              <field column="price" name="product_price"/>              <field column="description" name="product_description"/>              <field column="picture" name="product_picture"/>         </entity>       </document>       </dataConfig>5.6 点击“execute”按钮导入数据注意:导入数据前会先清空索引库,然后再导入。

创建POJO

        //商品        public class Product {            private String pid;            private String name;            private String price;            private String picture;            get/set...        }        //分页        public class Result {            private Integer curPage;// 当前页            private Integer pageCount;// 总页数            private Long recordCount;// 数据总条数            private List<Product> productList;// 商品结果集            get/set...        }

Controller

    @Controller    public class ProductController {        //注入service        @Resource        private ProductService productService;        /**         * 跳转商品搜索列表页面         */        @RequestMapping("list")        public String returnPage (String qName, String catelog_name, String price, String sort,@RequestParam(defaultValue="1") Integer page,Model model){            //调用service            PageBean pageBean = productService.queryProductIndex(qName, catelog_name, price, sort, page);            //查询参数回显            model.addAttribute("qName", qName);            model.addAttribute("catelog_name", catelog_name);            model.addAttribute("price", price);            model.addAttribute("sort", sort);            model.addAttribute("page", page);            //设置分页            model.addAttribute("result", pageBean);            return "product_list";        }    }

Service

        @Service("productService")        public class ProductServiceImpl implements ProductService {            //注入dao            @Resource            private ProductDao productDao;            @Override            public PageBean queryProductIndex(String qName, String catelog_name, String price, String sort, Integer page) {                //创建solr服务提供solrQuery封装参数对象                SolrQuery solrQuery = new SolrQuery();                //判断参数是否为空                if (qName != null && !qName.equals("")) {                    solrQuery.setQuery(qName);                } else {                    solrQuery.setQuery("*:*");                }                //设置过滤查询                if (catelog_name != null && !catelog_name.equals("")) {                    solrQuery.setFilterQueries("product_catalog_name:"+catelog_name);                }                //过滤价格                if (price != null && !price.equals("")) {                    //切分价格区间0-9                    String[] prices = price.split("-");                    //设置过滤查询                    solrQuery.addFilterQuery("product_price:["+prices[0]+"TO"+prices[1]+"]");                }                //排序                if (sort!=null && sort.equals("1")) {                    solrQuery.setSort("product_price",ORDER.desc);                } else {                    solrQuery.setSort("product_price",ORDER.asc);                }                //设置分页                int startNo = (page-1)*60;                solrQuery.setStart(startNo);                solrQuery.setRows(60);                //设置高亮                //开启高亮显示                solrQuery.setHighlight(true);                //指定高亮显示字段,高亮显示字段不能是复制域,只能是单个域                solrQuery.addHighlightField("product_name");                //设置高亮前缀                solrQuery.setHighlightSimplePre("<font color='red'>");                //设置高亮后缀                solrQuery.setHighlightSimplePost("</font>");                //设置默认查询字段                solrQuery.set("df","product_keywords");                //调用dao查询索引库                PageBean pageBean = productDao.queryProductsIndex(solrQuery);                //获取总记录数                 Integer recordCount = pageBean.getRecordCount();                //计算总页码                int pages = recordCount/60;                if (recordCount%60>0) {                    pages++;                }                 //设置当前页                pageBean.setCurPage(page);                //设置总页码                pageBean.setPageCount(pages);                return pageBean;            }        }

Dao

        @Repository("productDao")        public class ProductDaoImpl implements ProductDao{            //注入solr远程对象服务            @Resource            private SolrServer solrServer;            @Override            public PageBean queryProductsIndex(SolrQuery solrQuery) {                //创建pageBean,用于封装分页信息                PageBean pageBean = new PageBean();                try {                    //调用远程solr服务,使用solrQuery封装参数对象,直接查询远程索引库                    QueryResponse response = solrServer.query(solrQuery);                    //获取命中总记录数                    SolrDocumentList solrDocumentList = response.getResults();                    Long numFound = solrDocumentList.getNumFound();                    //把总记录数封装到pagebean中                    pageBean.setRecordCount(numFound.intValue());                    //创建list集合,封装商品数据                    List<Products> pList = new ArrayList<Products>();                    //循环获取文档数据集合                    for (SolrDocument solrDocument : solrDocumentList) {                        //创建商品对象,封装从索引库中查询出文档商品数据                        Products product = new Products();                        //获取文档数据                        String id = (String) solrDocument.get("id");                        product.setPid(id);                        String product_name = (String) solrDocument.get("product_name");                        //获取高亮                        Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();                        //第一个map的key就是高亮文档的id                        Map<String, List<String>> map = highlighting.get(id);                        //第二个map的key就是高亮字段域名称                        List<String> list = map.get("product_name");                        //判断高亮是否存在                        if (list != null && list.size() > 0) {                            product_name = list.get(0);                        }                        product.setName(product_name);                        Float product_price = (Float) solrDocument.get("product_price");                        product.setPrice(product_price);                        String product_picture = (String) solrDocument.get("product_picture");                        product.setPicture(product_picture);                        //将商品添加到集合中                        pList.add(product);                    }                    //将商品集合封装到pagebean中                    pageBean.setProductList(pList);                } catch (SolrServerException e) {                    e.printStackTrace();                }                return pageBean;            }        }
0 0
原创粉丝点击