A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 余大麻 中级黑马   /  2018-12-6 11:10  /  1070 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

1.solr概要A.solr简介
  • Solr是Apache下的一个顶级开源项目,底层是由lucene实现的全文搜索服务
  • solr已经把lucene封装成一个web项目,我们用的时候只需要安装和配置
    • 安装比较简单(直接解压war包)
    • 配置比较麻烦(从自带的netty服务器迁移到tomcat服务器)
  • solr作用
    • 使用solr实现站内搜索功能
    • 使用传统的数据库查询方式实现搜索无法满足一些高级的搜索需求
  • solr操作流程
    • 通过post请求进行增删改
    • 通过get请求进行查询

B.solr和lucene区别
  • lucene是一个全文搜索的工具包,让开发人员自己扩展
  • solr是封装了lucene的全文搜索服务
2.solr安装(解压war包-->补全jar包-->配置solrHome)A.解压war包
  • 创建一个空文件夹solrService
    • 解压一个新的tomcat7.0以上版本到当前文件夹
    • 解压solr的压缩包到当前文件夹
    • 创建一个文件夹:solrHome

B.把war包拷贝到tomcat的webapp下
  • 发布solr工程
    • 从netty中迁移到tomcat中
  • 在solr文件夹--->example--->webapps--->solr.war
    • 复制到tomcat--->webapps--->粘贴
    • 解压war包在当前目录,完成后删除war包
      • 因为需要往项目里配置依赖包,
      • 不然每次启动tomcat都会解压一次solr.war


C.补全迁移中缺少的jar包
  • solr官方把工程整合到netty中
    • 项目需要的jar包没有完全放到solr.war中
    • 有一部分在netty服务器里
    • 我们需要把缺少的jar包补全
  • tomcat有两处存放jar包的地方
    • 项目里面(推荐)
    • tomcat的lib文件夹里
  • 在刚刚拷贝war的上级目录--->lib--->ext--->5个jar包--->复制
    • 粘贴到tomcat项目下的solr的WEB-INF的lib中

D.配置solr的家(索引库)
  • 原生solr工程的索引库在netty工程里的,我们要迁移出来
    • 在tomcat同级目录创建solrHome目录,用于存储索引(便于集群的时候可以统一存放目录)
    • 把solr解压包中--->example---solr目录下的所有文件拷贝到刚刚的目录下(soleHome)

E.配置家目录
  • 在tomcat中的solr项目中,在WEB-INF中 * web.xml是tomcat的配置文件 * weblogic.xml是weblogic服务器的配置文件
    • 打开web.xml文件,在第40行: <env-entry>把注释去掉,value值改成我们刚刚创建的家目录: solrData
      • 绝对路径


F.启动tomcat--->ok
  • localhost:8080/solr
提示:solrHome中有关配置
  • 刚拷贝得到的solrHome是solr存放索引的位置,其中collection1文件夹是其中一个solrcore
  • 我们需要关注这个文件夹下的collection1-->conf--->schema.xml,用于定义项目中用到的file名称
2.索引的操作A.添加索引库
  • 在solr工程页面添加索引库会报错
    • 我们的工程迁移不完整
    • 我们可以手动在solrHome目录手动添加
  • 我们可以拷贝一份solrHome里的collection1,改个名字
    • 但是拷贝后要修改core.properties文件里的配置跟文件夹名一致
  • 添加完毕后重启服务器
    • 一般一个公司就用一个核,很少用两个
  • solr后台界面(localhost:8080/solr),然后就可以看到我们刚手动添加的索引库了
5.中文分析器配
  • 每个核中有很多配置文件,我们只需关注2个
    • schema.xml---->用于配置域
      • 之前我们用lucene时是手动写field的,使用solr把域写好在配置文件中使用
    • solrconfig.xml---->用于自定义Filed域

A.Schema.xml
  • schema.xml,在SolrCore的conf目录下,不同的collection有不同的shema.xml,它是solr数据表的配置文件
  • FieldType域类型定义
    • 定义File的类型,定义这个类型的file是否需要分析,索引,保存和定义是否什么分析器
  • Field定义
    • 我们自己定义的file名称,需要基于FileType来确定是否分析,索引,保存,使用分析器类型等
  • uniqueKey
    • Solr中默认定义唯一主键key为id域,如下:
      • <uniqueKey>id</uniqueKey>
    • Solr在删除、更新索引时使用id域进行判断,也可以自定义唯一主,注意在创建索引时必须指定唯一约束
  • copyField复制域
    • copyField复制域,可以将多个Field复制到一个Field中,以便进行统一的检索
    • 如我们的document使用的cat,name,manu中的一个或者多个
      • 分别保存索引后,后台会主动将使用过的file整合到一个叫text的域中
      • 便于我们以后使用搜索的时候用,text域内包含了cat,name,manu的内容合并


[XML] 纯文本查看 复制代码
<copyField source="cat" dest="text"/>
<copyField source="name" dest="text"/>
<copyField source="manu" dest="text"/>


dynamicField(动态域)
  • 动态字段就是不用指定具体的名称,只要定义字段名称的规则

[XML] 纯文本查看 复制代码
<dynamicField name="*_i"  type="int"    indexed="true"  stored="true"/>
<dynamicField name="*_is" type="int"    indexed="true"  stored="true"  multiValued="true"/>
<dynamicField name="*_s"  type="string"  indexed="true"  stored="true" />


B.安装中文分词器
  • 使用IKAnalyzer中文分析器
  • 把IKAnalyzer2012FF_u1.jar添加到solr/WEB-INF/lib目录下
  • 复制IKAnalyzer的配置文件和自定义词典和停用词词典到solr的classpath下
  • 在schema.xml中添加一个自定义的fieldType,使用中文分析器
[XML] 纯文本查看 复制代码
<!-- IKAnalyzer-->
<fieldType name="text_ik" class="solr.TextField">
    <analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>

  • 定义field,指定field的type属性为text_ik
[XML] 纯文本查看 复制代码
<!--IKAnalyzer Field-->
<field name="title_ik" type="text_ik" indexed="true" stored="true" />
<field name="content_ik" type="text_ik" indexed="true" stored="false" multiValued="true"/>
  • 重启tomca
C.设置业务系统Field
  • 如果不使用Solr提供的Field可以针对具体的业务需要自定义一套Field,如下是商品信息Field
[XML] 纯文本查看 复制代码
<!--product-->
<field name="product_name" type="text_ik" indexed="true" stored="true"/>
<field name="product_price"  type="float" indexed="true" stored="true"/>
<field name="product_description" type="text_ik" indexed="true" stored="false" />
<field name="product_picture" type="string" indexed="false" stored="true" />
<field name="product_catalog_name" type="string" indexed="true" stored="true" />

<field name="product_keywords" type="text_ik" indexed="true" stored="false" multiValued="true"/>
<copyField source="product_name" dest="product_keywords"/>
<copyField source="product_description" dest="product_keywords"/>


6.Solr管理索引库A.添加/更新文档
  • 在后台页面中添加|更新
B.批量导入数据
  • 使用dataimport插件批量导入数据
  • 把dataimport插件依赖的jar包添加到solrcore(collection1\lib)中
    • dist文件夹下:
      • solr-dataimporthandler-4.10.3.jar
      • solr-dataimporthandler-extras-4.10.jar
    • 没有lib包要创建lib包
  • 加入mysql的数据库驱动到lib文件夹里
  • 配置solrconfig.xml文件,添加一个requestHandler
    • collection-->conf-->solrconfig.xml

[XML] 纯文本查看 复制代码
<requestHandler name="/dataimport" 
class="org.apache.solr.handler.dataimport.DataImportHandler">
    <lst name="defaults">
        <str name="config">data-config.xml</str>
    </lst>
</requestHandler>


  • 创建一个data-config.xml,保存到collection1\conf\目录下
[XML] 纯文本查看 复制代码
<?xml version="1.0" encoding="UTF-8" ?>  
<dataConfig>   
    <dataSource type="JdbcDataSource"   
        driver="com.mysql.jdbc.Driver"   
        url="jdbc:mysql://localhost:3306/lucene"   
        user="root"   
        password="root"/>   
    <document>   
        <entity name="product" query="SELECT pid,name,catalog_name,price,description,picture FROM products ">
            <field column="pid" name="id"/> 
            <field column="name" name="product_name"/> 
            <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>


  • 重启tomcat
C.删除文档
  • 删除索引格式如下
  • 删除制定ID的索引
[XML] 纯文本查看 复制代码
<delete>
    <id>8</id>
</delete>
<commit/>

  • 删除查询到的索引数据
[XML] 纯文本查看 复制代码
<delete>
    <query>product_catalog_name:幽默杂货</query>
</delete>
<commit/>

  • 删除所有索引数据
[XML] 纯文本查看 复制代码
<delete>
    <query>*:*</query>
</delete>
<commit/>

7.查询索引
  • 通过/select搜索索引,Solr制定一些参数完成不同需求的搜索
A.使用SolrJ管理索引库
  • solrj是访问Solr服务的java客户端,提供索引和搜索的请求方法,SolrJ通常在嵌入在业务系统中
  • 依赖jar包
    • solrj-lib文件夹
    • solr-solrj-4.10.3.jar
    • 还需要solr-4.10.3--->example--->lib--->ext下的jar包

B.添加索引
  • 创建工程
  • 导入jar包
  • 使用HttpSolrServer对象建立连接
  • 创建一个SolrInputDocument对象,然后添加域
  • 将SolrInputDocument添加到索引库
  • 提交
[Java] 纯文本查看 复制代码
public void addDocument() throws Exception {
    "和solr服务器创建连接"
    "参数:solr服务器的地址"
    SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr");
    "创建一个文档对象"
    SolrInputDocument document = new SolrInputDocument();
    "向文档中添加域"
    "第一个参数:域的名称,域的名称必须是在schema.xml中定义的"
    "第二个参数:域的值"
    document.addField("id", "c0001");
    document.addField("title_ik", "使用solrJ添加的文档");
    document.addField("content_ik", "文档的内容");
    document.addField("product_name", "商品名称");
    "把document对象添加到索引库中"
    solrServer.add(document);
    "提交修改"
    solrServer.commit();
}

C.删除文档(根据id删除)
[Java] 纯文本查看 复制代码
public void deleteDocumentByid() throws Exception {
    "创建连接"
    SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr");
    "根据id删除文档"
    solrServer.deleteById("c0001");
    "提交修改"
    solrServer.commit();
}


D.根据查询删除
[Java] 纯文本查看 复制代码
public void deleteDocumentByQuery() throws Exception {
    SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr");
    solrServer.deleteByQuery("*:*");
    solrServer.commit();
}


E.修改文档
  • 在solrJ中修改没有对应的update方法,只有add方法,只需要添加一条新的文档,和被修改的文档id一致就,可以修改了,本质上就是先删除后添加
8.查询文档A.简单查询
[Java] 纯文本查看 复制代码
public void queryIndex() throws Exception {
    //创建连接
    SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr");
    SolrQuery query = new SolrQuery();
    query.setQuery("*:*");
    QueryResponse queryResponse = solrServer.query(query);
    SolrDocumentList solrDocumentList = queryResponse.getResults();
    System.out.println("共查询到商品数量:" + solrDocumentList.getNumFound());
    for (SolrDocument solrDocument : solrDocumentList) {
        System.out.println(solrDocument.get("id"));
        System.out.println(solrDocument.get("product_name"));
        System.out.println(solrDocument.get("product_price"));
        System.out.println(solrDocument.get("product_catalog_name"));
        System.out.println(solrDocument.get("product_picture"));
    }
}

B.复杂查询
  • 其中包含查询、过滤、分页、排序、高亮显示等处理
[Java] 纯文本查看 复制代码
public void queryIndex2() throws Exception {
    //创建连接
    SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr");
    //创建一个query对象
    SolrQuery query = new SolrQuery();
    //设置查询条件
    query.setQuery("钻石");
    //过滤条件
    query.setFilterQueries("product_catalog_name:幽默杂货");
    //排序条件
    query.setSort("product_price", ORDER.asc);
    //分页处理
    query.setStart(0);
    query.setRows(10);
    //结果中域的列表
    query.setFields("id","product_name","product_price","product_catalog_name","product_picture");
    //设置默认搜索域
    query.set("df", "product_keywords");
    //高亮显示
    query.setHighlight(true);
    //高亮显示的域
    query.addHighlightField("product_name");
    //高亮显示的前缀
    query.setHighlightSimplePre("<em>");
    //高亮显示的后缀
    query.setHighlightSimplePost("</em>");
    //执行查询
    QueryResponse queryResponse = solrServer.query(query);
    //取查询结果
    SolrDocumentList solrDocumentList = queryResponse.getResults();
    System.out.println("共查询到商品数量:" + solrDocumentList.getNumFound());
    for (SolrDocument solrDocument : solrDocumentList) {
        System.out.println(solrDocument.get("id"));
        "取高亮显示"
        String productName = "";
        Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
        List<String> list = highlighting.get(solrDocument.get("id")).get("product_name");
        "判断是否有高亮内容"
        if (null != list) {
            productName = list.get(0);
        } else {
            productName = (String) solrDocument.get("product_name");
        }
        System.out.println(productName);
        System.out.println(solrDocument.get("product_price"));
        System.out.println(solrDocument.get("product_catalog_name"));
        System.out.println(solrDocument.get("product_picture"));
    }
}

9.案例实现(JD商城)
  • 创建一个web工程导入jar包
  • springmvc的相关jar包
  • solrJ的jar包
  • Example\lib\ext下的jar包
[XML] 纯文本查看 复制代码
"springmvc.xml"
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
        
    <context:component-scan base-package="com.itheima.jd"/>
    <!-- 配置注解驱动,如果配置此标签可以不用配置处理器映射器和适配器 -->
    <mvc:annotation-driven/>
    <!-- 配置视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    <!-- SolrServer的配置 -->
    <bean id="httpSolrServer" class="org.apache.solr.client.solrj.impl.HttpSolrServer">
        <constructor-arg index="0" value="http://localhost:8080/solr"/>
    </bean>
</beans>


[XML] 纯文本查看 复制代码
"web.xml"
<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <!-- 
            指定springmvc配置文件的路径 
            如果不指定默认为:/WEB-INF/${servlet-name}-servlet.xml
        -->
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc.xml</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>*.action</url-pattern>
</servlet-mapping>
<!-- 解决post乱码问题 -->
<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>utf-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>




















0 个回复

您需要登录后才可以回帖 登录 | 加入黑马