SOLR:APACHE版solr环境搭建及作为Hbase二级索引使用

一:课程计划

1、 solr介绍
2、 solr安装配置(重点)
3、 solr的基本使用(重点)
4、 solrj的使用(重点)
5、 hbase + solr代码示例

二: Solr介绍

2.1 什么是solr

Solr也是Apache下一个项目,它是使用java开发的,它是基于Lucene的全文搜索服务器。
Solr如何进行索引和搜索
索引:客户端(可以是浏览器可以是java程序)发送post请求到solr服务器,发给solr服务器一个文档(xml、json),就可以进行一个添加索引删除索引、修改索引的操作。
搜索:客户端(可以是浏览器可以是java程序)发送get请求到solr服务器,请求solr服务器给它响应一个结果文档(xml、json),程序员拿到这些文档就可以对其进行解析。进行视图渲染。
Solr本身没有UI界面的功能。

2.2 solr + hbase

实现原理:
1. 在向Hbase增、删时同时把涉及条件过滤的字段和rowkey在Solr中建立索引;
2. 通过Solr的多条件查询快速获得符合过滤条件的rowkey;
3. 拿到这些rowkey之后在HBASE中通过指定rowkey进行查询。
这里写图片描述

2.3 Solr和lucene的区别

Lucene是一个全文检索的工具包,它是一堆jar包,不能单独运行,即不能独立对外提供服务。
Solr是一个全文搜索服务器,它可以独立运行,它能独立对外提供搜索和索引服务。
使用lucene开发站内搜索的话,程序员编写的代码量会比较大,而且在搜索和索引流程得考虑他的性能。
使用solr开发站内搜索的话,程序员只需编写少量的代码,快速的搭建出来站内搜索功能。而且性能方面不需要程序员去考虑,solr对它已经进行了处理。
这里写图片描述

三: Solr安装配置

3.1 Solr下载

Solr和lucene的版本是同步更新的

下载地址:http://archive.apache.org/dist/lucene/solr/
下载版本:5.2.0
这里写图片描述
目录:
这里写图片描述
bin:solr的脚本
Contrib:solr为了增强自身的功能,所添加的扩展依赖包
Dist:solr build过程时产生的war包和jar包,还有它的一些依赖包
Docs:文档
Example:例子目录

3.2 SolrCore的安装配置

3.2.1 Solrhome和SolrCore

Solrhome是一个目录,它是solr运行的主目录,它包括多个SolrCore目录,SolrCore目录中就solr实例的运行配置文件和数据文件。
Solrhome中可以包括多个SolrCore,每个SolrCore互相独立,而且可以单独对外提供搜索和索引服务。

3.2.2 SolrHome

Solrhome的位置:
这里写图片描述
将此目录copy到其他位置为了便于理解将此命名为:solrHome。
这里写图片描述

3.2.3 SolrCore

SolrCore位置:
这里写图片描述
将此solr文件夹copy到刚才的solrHome文件夹中、为了方便理解将此命名为solrCore0(改名称后目录下core.properties里名称也要改)
这里写图片描述
在solrCore0下新建文件夹data
这里写图片描述
在data下新建文件夹index、tlog
这里写图片描述

3.3 Solr部署到Tomcat

Solr需要运行一个servlet容器,它默认通过了一个servlet容器:jetty(java写的),项目中大多使用的是Tomcat

3.3.1 把solr的war部署到Tomcat中
  1. solr.war的位置:
    这里写图片描述

  2. 复制到tomcat的webapps下、tomcat执行以下会生成solr文件夹、将solr.war删除
    这里写图片描述

  3. 添加扩展依赖包、将如下位置的jar、copy到tomcat/webapps/solr/WEB-INF/lib
    这里写图片描述

  4. 添加log4j日志配置文件:在如下目录下新建文件夹classes用于存放配置文件
    这里写图片描述

  5. Log4j配置文件位置:(将此文件copy到classes中)
    这里写图片描述

  6. 在web.xml中指定solrhome的位置
    这里写图片描述

    3.3.2 启动Tomcat进行访问

    这里写图片描述

    3.3.2.1 访问地址

    http:/xxxxxxxxx:8080/solr/
    这里写图片描述
    看到该界面表示安装成功。

3.4 界面功能介绍

3.4.1 Analysis

这里写图片描述

3.4.2 Document

通过该界面操作,可以对索引库进行添加索引、删除索引、修改索引
在solr中,添加或修改文档时,必须要传入一个唯一主键id
这里写图片描述

3.4.3 Query

q:查询
fq:过滤
sort:排序
start,rows:一看就是分页其他自己摸索
这里写图片描述

3.5 多SolrCore配置

一个solr工程中可以配置多个SolrCore实例。
配置多个SolrCore实例有啥好处:
1、 一个solr工程配置多个SolrCore,而且每个solrcore之间是互相独立,可以单独对外提供搜索和索引服务。这类似于数据库。一个数据库可以有多个实例。如果有新需求,可以直接扩展实例。
2、 多Solrcore在管理索引文件时,可以进行分类管理。
3、 使用solrcloud(solr集群)必须要建立多SolrCore。
复制solrhome下的solrCore0到本目录下,并且改名为solrCore1
修改solrCore1文件中core.properties
这里写图片描述

四: Solr的基本使用

4.1 Schema.xml

Schema.xml文件在SolrCore中conf目录下。这个文件主要 是配置域名及域的类型等信息。Solr中的域要先定义后使用。
文件位置:
这里写图片描述

4.1.1 Field(重点)

配置solr的域:

<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />

Name:域名
Type:域的类型(也需要配置)
Indexed:是否索引
Stored:是否存储
Required:是否必须,一般只有id才设置
multiValued:是否可以多值。如果设置多值的话,里面的值就采用数组方式存储。比如商品图片(大图、中图、小图等等)

4.1.2 dynamicField

配置动态域:

<dynamicField name="*_i"  type="int"    indexed="true"  stored="true"/>

Name:指定域的名称,该域的名称是通过一个表达式来指定的
Type:域的类型(在使用动态域的时候,要分清该域对应的类型)

4.1.3 uniqueKey

指定一个主键的域,每个文档中都应该有一个唯一主键

<uniqueKey>id</uniqueKey>
4.1.4 copyField

复制域,将源域的内容复制到目标域中:

<copyField source="cat" dest="text"/>

Source:源域
Dest:目标域
目标域:

<field name="text" type="text_general" indexed="true" stored="false" multiValued="true"/>
4.1.5 fieldType(重点)

配置域的类型

<fieldType name="text_general" class ="solr.TextField" positionIncrementGap="100">
      <analyzer type="index">
        <tokenizer class="solr.StandardTokenizerFactory"/>
        <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
        <!-- in this example, we will only use synonyms at query time
        <filter class="solr.SynonymFilterFactory" synonyms="index_synonyms.txt" ignoreCase="true" expand="false"/>
        -->
        <filter class="solr.LowerCaseFilterFactory"/>
      </analyzer>
      <analyzer type="query">
        <tokenizer class="solr.StandardTokenizerFactory"/>
        <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
        <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
        <filter class="solr.LowerCaseFilterFactory"/>
      </analyzer>
    </fieldType>

Name:域的类型的名称
Class:指定solr的类型
Analyzer:配置分词器
Type:index(索引分词器)、query(搜索分词器)
Tokenizer:分词器
Filter:过滤器

4.2 配置中文分词器

使用ikAnalyzer中文分词器
1、 把IKAnalyzer-5.0.jar添加到solr/WEB-INF/lib目录下
2、 复制IKAnalyzer的配置文件和自定义词典和停用词词典到solr的classpath下。
这里写图片描述
3、 配置fieldType,指定使用中文分词器
这里写图片描述
4、 配置field,使用中文分词器的fieldType

<field name="titleIK" type="test_ik" stored="true" required="false" multiValued="false" />

5、 重启Tomcat测试
这里写图片描述

4.4 DataimportHandler

DataimportHandler,它可以把数据从关系数据库中查询出来,然后倒入到索引库中。自己去研究、觉得实际用处不大就没尝试。

五:Solrj的使用

5.1 什么是solrj

Solrj是访问solr服务的java程序客户端。
这里写图片描述

5.2 需求

使用solrj调用solr服务实现对索引库的增删改查操作。

5.3 环境准备

说明:我的solr版本是5.2.0,以下版本4.10.3。但solrJ的使用都是一致的。以下会有很多特殊字符博客转换比较麻烦、因此直接拿之前的文档截图
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

public class IndexSearch {

    @Test
    public void search() throws Exception {
        // 创建HttpSolrServer,可以访问solr服务
        // 参数就是solr服务的url
        HttpSolrServer server = new HttpSolrServer("http://localhost:8080/solr");

        // 创建solrQuery对象
        SolrQuery query = new SolrQuery();
        // 设置q,查询条件
        query.set("q", "product_name:小黄人");
        // 设置fq,过滤查询条件
        query.set("fq", "product_catalog_name:幽默杂货");

        // 设置sort,排序
        query.set("sort", "product_price desc");

        // 设置start、rows,分页信息(写上默认值)
        query.setStart(0);
        query.setRows(10);

        // 设置fl,即要显示的域的列表
        // query.set("fl", "");

        // 设置df"
        query.set("df", "product_keywords");

        // 设置高亮
        query.setHighlight(true);
        query.addHighlightField("product_name");
        query.setHighlightSimplePre("<font style=\"color:red\">");
        query.setHighlightSimplePost("</font>");

        // 执行搜索,并获得返回值
        QueryResponse response = server.query(query);

        // 根据查询条件匹配出的结果对象
        SolrDocumentList list = response.getResults();
        // 匹配出的结果总数
        long count = list.getNumFound();

        System.out.println("匹配出的结果总数:" + count);

        //获取高亮信息
        Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();
        for (SolrDocument solrDocument : list) {
            System.out.println("商品id:" + solrDocument.get("id"));
            System.out.println("商品名称:" + solrDocument.get("product_name"));
            System.out.println("商品分类:" + solrDocument.get("product_catalog"));
            System.out.println("商品分类名称:"
                    + solrDocument.get("product_catalog_name"));
            System.out.println("商品价格:" + solrDocument.get("product_price"));
            // System.out.println("商品描述:"+solrDocument.get("product_description"));
            System.out.println("商品图片地址:" + solrDocument.get("product_picture"));

            List<String> list2 = highlighting.get(solrDocument.get("id")).get("product_name");
            if(list2!=null){
                System.out.println("高亮后的信息:"+list2.get(0));
            }
        }


    }
}

六: hbase + solr代码示例

6.1插入hbase的同时向solr中添加索引

是不是感觉很别扭、hbase增、删、改的同时还要修改solr索引。CDH版hbase-indexer解决了hbase增、删、改solr自动关联问题。请查看hbase-indexer那篇博客…

/**
     * 插入Hbase的同时向solr中添加索引
     * @throws Exception
     */
    public static void put() throws Exception { 
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd H:m:s");
        HttpSolrServer solrServer = new HttpSolrServer(
                "http://192.168.136.130:8080/solr/solrCore0"); 
        List<Map<String,String>> dataList = new ArrayList<Map<String,String>>();
        System.out.println("============start======" + format.format(new Date()));
        String[] relation = {"friend","colleague"};
        String[] loanlevel = {"1","2","3","4","5"};
        for(int i=0;i<1000000;i++){
            // 
            String f1Str = (int)(Math.random()*1000000) + "";
            String f2Str = relation[((int)(Math.random()*2))];
            String f3Str = loanlevel[((int)(Math.random()*5))];
            // 插入Hbase
            Map<String, String> mapData = new HashMap<String,String>();
            mapData.put("rowKey", "rk" + i);
            mapData.put("f1", f1Str);
            mapData.put("f2", f2Str);
            mapData.put("f3", f3Str);
            dataList.add(mapData);
            mapData = null;
            // 插入solr
            SolrInputDocument solrDoc = new SolrInputDocument();
            solrDoc.addField("rowkey", "rk" + i);
            solrDoc.addField("f1", f1Str);
            solrDoc.addField("f2", f2Str);
            solrDoc.addField("f3", f3Str);
            solrServer.add(solrDoc);
            solrDoc.clear();
            solrDoc = null;
        }
        HBaseUtil.insertBatch("student", "info", dataList);
        solrServer.commit(true, true, true);
        System.out.println("=======111====end========" + format.format(new Date()));
}

6.2在solr中通过索引得到rowkey、拿到rowkey去hbase中取数据

final Configuration conf;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd H:m:s");
        HttpSolrServer server = new HttpSolrServer("http://192.168.136.130:8080/solr/solrCore0"); 
        HTable table = HBaseUtil.getNewTable("student");

        Get get = null;
        List<Get> list = new ArrayList<Get>();
        // solr查询条件
        SolrQuery query = new SolrQuery("f2:colleague AND f3:3");
        query.setStart(0); //数据起始行,分页用
        query.setRows(100); //返回记录数,分页用
        QueryResponse response = server.query(query);
        SolrDocumentList docs = response.getResults();
        // 获得rowkey集合
        for (SolrDocument doc : docs) {
            get = new Get(Bytes.toBytes((String) doc.getFieldValue("rowkey")));
            list.add(get);
        }
        // 通过rowkey集合在hbase取数据
        Result[] res = table.get(list);
        int i = 0;
        for (Result rs : res) {
            i++;
            if(i < 4){
                log.info("=======================result====:" + rs.toString());
            }
        }
        table.close();
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值