solr学习笔记(SolrJ)

本文介绍如何搭建Solr搜索服务,包括安装配置过程、SolrCore的概念及管理方式,以及通过SolrJ API进行数据操作的方法。涵盖索引库配置、数据增删改查等关键知识点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

solr学习笔记

#

1.概述

  • 企业级搜索应用服务:本质是war包,底层是lucene,比lucene更高效,实现了可配置,可扩展。
  • 安装
    • 本质是一个war包,按照正常的web工程发布方式,解压到tomcat的webapps目录下。
    • 将下载文件目录中的solr单独拷出来,放在一个没有中文的路径下(这是solr的home文件夹,存储索引库等)
    • 1.可以打开tomcat/bin/catalina.bat文件,在文件首行添加:set “JAVA_OPTS=-Dsolr.solr.home=【solr文件夹路径】”
    • 2.或者打开solr项目的web.xml进行如下配置


    • solr/home
      d:\solrhome
      java.lang.String
    • 配置分词器:在web-INF路径下创建classes文件夹(classpath),防止IK分词器配置文件(具体内容,见lucene笔记)。
    • jar包引用:将相关依赖的jar包放入web-INF下的lib文件夹中。
    • 启动tomcat,即可通过浏览器访问solr库。

2.SolrCore

  • 在Solr中,每一个Core代表一个索引库,里面包含索引数据及其配置信息。Solr中可以拥有多个Core,也就是同时管理多个索引库,就像在MySQL中可以有多个database。存储位置在solrhome文件夹中。
  • 常用配置文件

    • conf/schema.xml:字段及字段约束信息

      • Field字段的属性信息。
        • name:字段名称,最好以下划线或者字母开头
        • type:字段类型,指向的是本文件中的标签
        • indexed:是否创建索引
        • stored:是否被存储
        • multiValued:是否可以有多个值,如果字段可以有多个值,设置为true
      • FieldType
        • name:字段类型的名称,可以自定义
        • class:字段类型在Solr中的类。
        • analyzer:这个子标签用来指定分词器
      • 唯一主键
        • uniqueKey标签
      • 动态字段
        • 标签:dynamicField name=”item_spec_*” type=”string” indexed=”true” stored=”true”
    • conf/solrconfig.xml:索引库的相关配置

      • lib标签:配置插件依赖的jar包
    • core.properties:Core的属性文件,记录当前core的名称等信息,也可以不写内容。

3.SolrJ

  • 概述:SolrJ是Apache官方提供的一套Java开发的,访问Solr服务的API
  • 依赖

  • <dependencies>
    <dependency>
    <groupId>org.apache.solr</groupId>
    <artifactId>solr-solrj</artifactId>
    <version>4.10.2</version>
    </dependency>
    <!-- Solr底层会使用到slf4j日志系统 -->
    <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.22</version>
    </dependency>
    <dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.2</version>
    </dependency>
    </dependencies>
  • 添加/修改字段

    • document添加

      public void addDateToSolr() throws SolrServerException, IOException{
      //solrCore访问地址
      String url = "http://localhost:8080/solr/core2";
      //solrj连接对象
      HttpSolrServer server = new HttpSolrServer(url);
      SolrInputDocument document = new SolrInputDocument();
      // 新增数据,数据封装对象 SolrInputDocument  提供了addField("字段名称", "字段值")设置数据
      document.addField("id", 2);
      document.addField("name", "solr");
      document.addField("age", 27L);
      document.addField("title", "solr是独立的企业级搜索服务器");
      List<SolrInputDocument> list = new ArrayList<SolrInputDocument>();
      list.add(document);
      //添加数据
      server.add(list);
      //提交数据
      server.commit();
      }
      
    • javaBean添加

      public void addJavaBeanToSolrCore() throws IOException, SolrServerException{
      String url = "http://localhost:8080/solr/core2";
      HttpSolrServer server = new HttpSolrServer(url);
      //同时新增多条数据
      List<User> list = new ArrayList<User>();
      for(int i = 3;i<30;i++){
          User user = new User();
          user.setId(""+i);
          user.setName("程序员"+i+"号");
          user.setAge(Long.valueOf(""+i));
          user.setTitle("机智聪明勤奋工程师"+i);
          list.add(user);
      }
      
      //直接添加javaBean  添加单条数据
      //server.addBean(user);
      server.addBeans(list);
      //提交
      server.commit();    
      }
      

注意:这里的User类的成员变量需要与field匹配。需要在User类的成员变量上添加@Field注解

  • 修改字段

    • 注意: solr中并没有更新数据的方法,没有更新这个概念
      • 更新是怎么回事?
      • 通过唯一字段来判断 schema.xml中定义了uniqueKey就是唯一字段
      • 如果新增数据的唯一键已经存在,新增时会直接全覆盖
      • 如果新增数据时唯一键不存在,直接新增
  • 删除字段

    • 根据Id

      public void deleteById() throws SolrServerException, IOException{
          String url = "http://localhost:8080/solr/core2";
          HttpSolrServer server = new HttpSolrServer(url);
          //根据id删除对应的数据
          server.deleteById("2");
          server.commit();
      }   
      
    • 根据Id集合(方法重载)

      public void deleteByIds() throws SolrServerException, IOException{
          String url = "http://localhost:8080/solr/core2";
          HttpSolrServer server = new HttpSolrServer(url);
          //根据id删除对应的数据
          List<String> ids = new ArrayList<String>();
          ids.add("1");
          ids.add("3");
          //根据ids删除指定的数据
          server.deleteById(ids);
          server.commit();
      }
      
    • 根据查询条件

      public void deleteByQuery() throws SolrServerException, IOException{
          String url = "http://localhost:8080/solr/core2";
          HttpSolrServer server = new HttpSolrServer(url);
          String query = "title:聪明";
          //根据指定的查询条件删除  删除所有匹配的结果
          server.deleteByQuery(query);
          server.commit();
      }
      
  • 查找字段

    • 普通查询

      public void searchSolrCore() throws SolrServerException{
          String url = "http://localhost:8080/solr/core2";
          HttpSolrServer server = new HttpSolrServer(url);
      
          //字段名:参数值
          //SolrQuery query = new SolrQuery("title:互*");
          //布尔搜索
          //SolrQuery query = new SolrQuery("title:solr OR title:iphone");
          //子表达式查询(布尔搜索)
          //SolrQuery query = new SolrQuery("(title:solr OR title:聪明) OR (title:iphone)");
          //相似度搜索,最大允许编辑次数为2次,这里设置为1
          //SolrQuery query = new SolrQuery("iphon~1");
          //数字范围搜索  包含起始值和结束值
          SolrQuery query = new SolrQuery("age:[17 TO 27]");
          //{}:表示不包含   []:表示包含
      
          //根据id字段倒叙排列
          query.setSort("id", ORDER.desc);
          QueryResponse response = server.query(query);
      
          //解析搜索的结果集方式一:返回list集合
          SolrDocumentList list = response.getResults();
          for(SolrDocument sd : list){
              System.out.println("id===="+sd.get("id"));
              System.out.println("name===="+sd.get("name"));
              System.out.println("title===="+sd.get("title"));
              System.out.println("===========next===========");
          }
      
          //解析搜索结果集的方式二  :直接返回javaBean的方式
          List<User> list = response.getBeans(User.class);
              for(User u : list){
                  System.out.println(u);
              }
          }
      )
      
    • 特殊查询

      • 分页及高亮

        public void searchSolrCorePageList() throws SolrServerException{
            String url = "http://localhost:8080/solr/core2";
            HttpSolrServer server = new HttpSolrServer(url);
            //页码
            Integer page = 2;
            //每页显示条数
            Integer pageSize = 15;
            Integer start = (page -1 ) * pageSize;
        
            //字段名:参数值
            SolrQuery query = new SolrQuery("title:聪明");
            //根据id字段倒叙排列
            query.setSort("id", ORDER.desc);
            //设置分页查询
            query.setStart(start);
            query.setRows(pageSize);
        
            //开启高亮显示(可以省略)
            //query.setHighlight(true);
        
            //高亮显示的标签前缀
            query.setHighlightSimplePre("<em color='red'>");
            //高亮显示的标签后缀
            query.setHighlightSimplePost("</em>");
            //添加需要高亮显示的字段
            query.addHighlightField("title");
            query.addHighlightField("name");
        
            QueryResponse response = server.query(query);
            //高亮显示的结果集
        
            // 外层的Map,key:id,value:id以外的其他高亮字段,可能有多个,也是一个Map
            // 内层的Map,key:高亮字段的名称,value:字段的内容,集合
            Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();
            //遍历的方式获取高亮的结果集
            for(String key : highlighting.keySet()){
                Map<String, List<String>> map = highlighting.get(key);
                for(String key2 : map.keySet()){
                    List<String> list = map.get(key2);
                    for(String str : list){
                        System.out.println(str);
                    }
                }
            }
        
            //解析搜索结果集的方式二  :直接返回javaBean的方式
            List<User> list = response.getBeans(User.class);
            for(User u : list){
                //对应map中取值的方法
                String highlightTilte = highlighting.get(u.getId()).get("title").get(0);
                System.out.println(highlightTilte);
                u.setTitle(highlightTilte);
                System.out.println(u);
            }
        }
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值