前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >day66_Solr学习笔记

day66_Solr学习笔记

作者头像
黑泽君
发布2018-12-05 14:54:13
1.2K0
发布2018-12-05 14:54:13
举报
文章被收录于专栏:黑泽君的专栏黑泽君的专栏

1、Solr介绍

1.1、什么是solr

   Solr 是Apache下的一个顶级开源项目采用Java开发,它是基于Lucene全文搜索服务器。Solr可以独立运行JettyTomcat等这些Servlet容器中。可以单独对外提供搜索和索引功能。    Solr提供了比Lucene更为丰富的查询语言,同时实现了可配置可扩展,并对索引搜索性能进行了优化。   使用Solr 进行创建索引和搜索索引的实现方法很简单,如下: 创建索引:客户端(可以是浏览器也可以是Java程序)用 POST 方法Solr 服务器发送一个描述 Field 及其内容的 XML 文档,Solr 服务器根据xml文档添加、删除、更新索引 。 搜索索引:客户端(可以是浏览器也可以是Java程序)用 GET方法Solr 服务器发送请求,然后对 Solr服务器返回xml、json等格式的查询结果进行解析,组织页面布局。        Solr不提供构建页面UI的功能,但是Solr提供了一个管理界面通过管理界面可以查询Solr的配置和运行情况。   Solr和Lucene没有视图渲染的功能。

1.2、Solr和Lucene的区别

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

2、Solr安装和配置(重点)

2.1、下载solr

Solr和Lucene的版本是同步更新的,最新的版本是7.5.0。 本课程使用的版本:4.10.3 下载地址:http://archive.apache.org/dist/lucene/solr/ 下载版本:4.10.3   Linux下需要下载 lucene-4.10.3.tgz   windows下需要下载 lucene-4.10.3.zip 下载lucene-4.10.3.zip并解压:

目录结构详解如下:

  bin:solr的运行脚本。

  contrib:solr的一些扩展jar包,用于增强solr的功能。

  dist:该目录包含build过程中产生的war和jar文件,以及相关的依赖文件。

  docs:solr的API文档。

  example:solr工程的例子目录:

example/solr

     该目录是一个标准的SolrHome目录,它包含一个默认的SolrCore目录collection1。

SolrHome目录

SolrCore目录

     SolrHome是Solr运行的主目录,该目录中包括了多个SolrCore目录。SolrCore目录中包含了运行Solr实例所有的配置文件和数据文件,Solr实例就是SolrCore

一个SolrHome可以包括多个SolrCore(Solr实例),每个SolrCore提供单独的搜索和索引服务。

example/multicore

     该目录包含了在Solr的multicore中设置的多个Core目录。

example/webapps

     该目录中包括一个solr.war,该war可作为solr的运行实例工程。

  licenses:solr相关的一些许可信息。

2.2、solr的运行环境

  solr 需要运行在一个Servlet容器中,Solr4.10.3要求jdk使用1.7以上,Solr默认提供Jetty(java写的Servlet容器),本教程使用Tocmat作为Servlet容器,相关环境如下:   solr:4.10.3   jdk环境:jdk1.8.0_161(solr4.10 不能使用jdk1.7以下)   Web服务器(servlet容器):Tomcat 8X   Mysql:5X

2.3、初始化数据库脚本

2.4、solrhome和solrcore的安装

第一步:安装tomcat,注意:我们学习的每一个服务器需要单独整一个tomcat,安装tomcat后需要进行相关配置。   配置参考连接:https://cloud.tencent.com/developer/article/1353297 第二步:把solr.war部署到Tomcat中,即将以下的war包,拷贝到tomcat的webapps目录下   从solr解压包下的solr-4.10.3\example\webapps目录中拷贝solr.war

第三步:使用压缩工具解压或者启动tomcat自动解压solr.war包,解压缩之后,将solr.war包删掉

第四步:添加solr的扩展服务包,jar包位置:solr-4.10.3\example\lib\ext

  将以上jar包,添加到以下目录:apache-tomcat-8.5.30-solr\webapps\solr\WEB-INF\lib

第五步:添加log4j.properties,将以下目录的文件进行拷贝,文件位置:solr-4.10.3\example\resources\log4j.properties

  复制到以下目录:如果没有该目录就创建它

第六步:在solr应用的web.xml文件中,指定solrhome的目录

  solr/home名称必须是固定的。

第七步:solrcore的安装,安装solrcore需要先安装solrhome,前面几步我们已经安装好了solrhome了。

  打开solr解压包下solr-4.10.3\example\solr文件夹,复制以下目录:

  粘贴到以下目录中(就是刚创建的solrhome目录):

  这样solrhome和solrcore就安装成功了。

2.5、solrcore的配置

在solrcore的conf文件夹下有一个solrconfig.xml。这个文件是用来配置SolrCore实例的相关信息。如果使用默认配置可以不用做任何修改。

它里面包含了不少标签,但是我们关注的标签为:lib标签、datadir标签、requestHandler标签。

2.5.1、lib 标签

solrcore需要添加一个扩展依赖包,通过lib标签来指定依赖包的地址。 即:在solrconfig.xml中可以加载一些扩展的jar,solr.install.dir:表示solrcore的目录位置(安装目录),需要如下修改:

然后将contrib和dist两个目录拷贝到E:\solr下,如下图:

2.5.2、datadir标签

每个solrcore都有自己的索引文件目录,默认在solrcore目录下的data中。

data数据目录下包括了index索引目录tlog日志文件目录

如果不想使用默认的目录也可以通过solrconfig.xml更改索引目录 ,如下:

2.5.3、requestHandler标签

requestHandler请求处理器,定义了索引和搜索的访问方式。 通过/update维护索引,可以完成索引的添加、修改、删除操作。

提交xml、json数据完成索引维护,索引维护小节详细介绍。

通过/select搜索索引。

设置搜索参数完成搜索,搜索参数也可以设置一些默认值,如下:

代码语言:javascript
复制
<requestHandler name="/select" class="solr.SearchHandler">
    <!-- 设置默认的参数值,可以在请求地址中修改这些参数-->
    <lst name="defaults">
        <str name="echoParams">explicit</str>
        <int name="rows">10</int><!--显示数量-->
        <str name="wt">json</str><!--显示格式-->
        <str name="df">text</str><!--默认搜索字段-->
    </lst>
</requestHandler>

2.6、启动Tomcat访问solr服务

访问地址:http://localhost:8080/solr/

出现以下界面则说明solr安装配置成功!!!

2.7、solr管理界面功能介绍

2.7.1、Dashboard

  仪表盘,显示了该Solr实例开始启动运行的时间、版本、系统资源、jvm等信息。

2.7.2、Logging

  Solr运行日志信息。

2.7.3、Cloud

  Cloud即SolrCloud,即Solr云(集群),当使用Solr Cloud模式运行时会显示此菜单,该部分功能在第二个项目,即电商项目中会讲解。

2.7.4、Core Admin

  Solr Core的管理界面。在这里可以添加SolrCore实例。

2.7.5、Java Properties

  Solr在JVM 运行环境中的属性信息,包括类路径、文件编码、jvm内存设置等信息。

2.7.6、Tread Dump

  显示Solr Server中当前活跃线程信息,同时也可以跟踪线程运行栈信息。

2.7.7、Core selector(重点)

选择一个SolrCore进行详细操作,如下:

(1)Analysis(重点)

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

  注:solr中,分析器是绑定在域的类型中的

(2)Dataimport

  可以定义数据导入处理器,从关系数据库中将数据导入到Solr索引库中。

  默认没有配置,需要手工配置。

(3)Documents(重点)

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

  通过此菜单可以创建索引更新索引删除索引等操作,界面如下:

  • Overwrite="true" 表示solr在做索引的时候,如果文档已经存在,就用xml中的文档进行替换。
  • Commit Within="1000" 表示solr在做索引的时候,每隔1000(1秒)毫秒,做一次文档提交。为了方便测试也可以在Documents中立即提交,需要在后添加

(4)Files、Ping、Plugins/Stats这三个选项卡不重要,不解释了

(5)Query(重点)

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

(6)Replication、Schema Browser这两个选项卡不重要,不解释了

2.8、多个solrcore的配置

配置多SolrCore的好处:   1、一个solr工程对外通过SorlCore 提供服务,每个SolrCore相当于一个数据库,这个功能就相当于一个mysql可以运行多个数据库。   2、每个SolrCore之间是独立的,都可以单独对外提供服务。不同的业务模块可以使用不同的SolrCore来提供搜索和索引服务。   3、将索引数据分SolrCore存储,方便对索引数据管理维护。   4、在进行SolrCloud集群必须配置多SolrCore。 添加solrcore: 第一步:复制solrhome下的collection1目录到本目录下,修改名称为collection2

第二步:修改新的solrcore目录下的core.properties文件

这样多solrcore就配置完成了。

第三步:验证多solrcore是否配置成功

重新启动Tomcat访问solr服务。出现如下图所示:表示多solrcore配置成功了。

3、Solr的基本使用

3.1、schema.xml

schema.xml文件在solrcore的conf目录下,如下图。它是Solr数据表配置文件,在此配置文件中定义了以及域的类型还有其他一些配置,在solr中域必须先定义后使用,即:在solr中,Field和FieldType都需要先定义后使用

3.1.1、filed(域)

定义Field域:<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />   name:指定域的名称   type:指定域的类型,比如:指定是否分词   indexed:是否索引   stored:是否存储   required:是否必须   multiValued:是否是多值,存储多个值时设置为true,solr允许一个Field存储多个值,比如:存储一个用户的好友id(多个),商品的图片(多个,大图和小图)。

3.1.2、dynamicField(动态域)

定义动态域:<dynamicField name="*_i" type="int" indexed="true" stored="true"/>   name:动态域的名称,是一个表达式,*匹配任意字符,只要域的名称和表达式的规则能够匹配就可以使用。   例如:搜索时查询条件:product_i:钻石,就可以匹配这个动态域,可以直接使用,不用单独再定义一个product_i域。

3.1.3、uniqueKey

指定唯一键:<uniqueKey>id</uniqueKey>   相当于主键,每个文档中必须有一个id域。其中的id是在field标签中已经定义好的域名,而且该域要设置为required为true。一个schema.xml文件中必须有且仅有一个唯一键。

3.1.4、copyField(复制域)

定义复制域:<copyField source="cat" dest="text"/>   可以将多个field复制到一个field中,以便进行统一的检索。当创建索引时,solr服务器会自动的将源域的内容复制到目标域中。   source:源域域名。   dest:目标域域名,搜索时,指定目标域为默认搜索域,可以提高查询效率。 注意:由dest指定的目标域,必须设置multiValued为true(多值)。示例如下图(以text域为例): 定义目标域:

3.1.5、fieldType(域的类型)

定义域的类型:示例代码如下

代码语言:javascript
复制
    <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:指定分词器。在fieldType定义的时候最重要的就是定义这个类型的数据在建立索引和进行查询的时候要使用的分析器analyzer,包括分词和过滤。   type:index和query。分别指定搜索和索引时的分析器。index 是创建索引,query 是查询索引。   tokenizer:指定分词器   filter:指定过滤器

3.2、配置中文分词器

使用IKAnalyzer中文分析器。 第一步:把IKAnalyzer2012FF_u1.jar添加到apache-tomcat-8.5.30-solr\webapps\solr\WEB-INF\lib目录下。

第二步:复制IKAnalyzer的配置文件、自定义词典和停用词词典到solr的classpath下,即:apache-tomcat-8.5.30-solr\webapps\solr\WEB-INF\classes。

第三步:在schema.xml中添加一个自定义的fieldType,使用中文分析器。

文件位置:E:\solr\solrhome\collection1\conf\schema.xml

第四步:在schema.xml中配置使用中文分词的field,即:定义field,指定field的type属性为text_ik。

第五步:重新启动Tomcat访问solr服务。测试结果如下:

name="title_ik"

name="content_ik"

3.3、配置业务的field

3.3.1、需求

要使用solr实现电商网站中商品搜索。 电商中商品信息在mysql数据库中存储了,将mysql数据库中数据在solr中创建索引。 需要在solr的schema.xml文件中定义商品field。即:对京东案例中的products表的数据进行索引,所以需要先定义对应的field域。

3.3.2、定义步骤

先确定定义的商品document的field有哪些? 可以根据mysql数据库中商品表的字段来确定: products商品表的表结构如下:

商品document的field包括:pid、name、catalog、catalog_name、price、description、picture

先定义fieldType

  经分析,由于中文分词器已经配置完fieldType,所以目前solr本身提供的fieldType类型够用了不用定义新的了。

再定义field

  pid:商品id主键

  由于pid在products表中是唯一键,而且在solr的shema.xml中已有一个id的唯一键配置,所以不需要再重新定义pid域。使用solr本身提供的即可,如下:

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

其余的需要自己定义,如下图所示:

定义目标域、定义复制域,如下图所示:

每次定义完新的域后都需要重新启动Tomcat访问solr服务,测试一下。没有问题,就可以开始下步操作啦!

3.4、dataimportHandler插件

该插件可以将数据库中指定的sql语句的结果导入到solr索引库中

3.4.1、第一步:添加所需的jar包

(1)添加dataimport的jar

从solr-4.10.3\dist目录下拷贝solr-dataimporthandler-4.10.3.jar,复制到以下目录:

修改E:\solr\solrhome\collection1\conf\solrconfig.xml文件,添加lib标签,如下:

<lib dir="${solr.install.dir:../..}/contrib/dataimporthandler/lib" regex=".*\.jar" />

(2)添加数据库驱动包

把mysql数据库驱动包,拷贝到以下目录:

修改solrconfig.xml文件,添加lib标签,如下:

<lib dir="${solr.install.dir:../..}/contrib/db/lib" regex=".*\.jar" />

3.4.2、第二步:配置solrconfig.xml,添加一个requestHandler
3.4.3、第三步:创建一个data-config.xml

在collection1\conf\目录下创建data-config.xml文件,内容如下:

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8" ?>  
<dataConfig>   
    <dataSource type="JdbcDataSource"   
                driver="com.mysql.jdbc.Driver"   
                url="jdbc:mysql://localhost: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>

data-config.xml文件详解如下:

3.4.4、第四步:重新启动Tomcat访问solr服务,测试一下

出现如下界面,表示我们配置dataimportHandler插件成功:

3.4.5、第五步:点击“Execute”按钮导入数据

即:将数据库中指定的sql语句的结果导入到solr索引库中,此过程可能需要一些时间,注意:导入数据前会先清空索引库,然后再导入。

我们可以通过点击“Refresh Status”按钮,查看导入数据的状态,最后导入数据成功的界面如下:

4、Solrj的使用

4.1、什么是solrj

solrj是访问Solr服务的java客户端,提供索引和搜索的请求方法,SolrJ通常嵌入在业务系统中,通过SolrJ的API接口操作Solr服务,如下图:

Solrj和图形界面操作的区别就类似于数据库中你使用jdbc和mysql客户端的区别一样。

4.2、需求

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

4.3、环境准备

  • Solr:4.10.3
  • jdk环境:jdk1.8.0_161(solr4.10 不能使用jdk1.7以下)
  • ide环境:Eclipse Oxygen

4.4、工程搭建

第一步:演示创建普通的java工程即可

第二步:添加jar

solrj的核心包和solrj的依赖包

solr服务的扩展包

4.5、使用solrj完成索引的维护

4.5.1、添加\修改索引

步骤   1、创建HttpSolrServer对象,通过它和solr服务器建立连接。   2、创建SolrInputDocument对象,然后通过它来添加域。   3、通过HttpSolrServer对象将SolrInputDocument添加到索引库。   4、提交。 在solr中,索引库中都会存在一个唯一键(唯一约束),如果一个document的id存在,则执行修改操作,如果不存在,则执行添加操作。

示例代码如下:

代码语言:javascript
复制
    /**
     * 使用solr添加\修改索引
     * @throws Exception
     */
    @Test
    public void insertAndUpdateIndex() throws Exception {
        // 1、创建HttpSolrServer对象,通过它和solr服务器建立连接。 
        HttpSolrServer server = new HttpSolrServer("http://localhost:8080/solr/"); // 参数:是solr服务器的访问地址
        // 2、创建SolrInputDocument对象,然后通过它来添加域。
        SolrInputDocument document = new SolrInputDocument();
        // 第一个参数:域的名称,域的名称必须是已经在schema.xml中定义过的
        // 第二个参数:域的值
        // 注意:id的域不能少
        document.addField("id", "c001");
        document.addField("name", "hello solr");
        // 3、通过HttpSolrServer对象将SolrInputDocument添加到索引库。 
        server.add(document);
        // 4、提交。 
        server.commit();
    }

图相化界面查询测试结果如下图所示:

4.5.2、删除索引

(1)根据指定ID来删除索引

代码语言:javascript
复制
    /**
     * 使用solr根据指定ID来删除索引
     * @throws Exception
     */
    @Test
    public void deleteIndexById() throws Exception {
        // 1、创建HttpSolrServer对象,通过它和solr服务器建立连接。 
        HttpSolrServer server = new HttpSolrServer("http://localhost:8080/solr/"); // 参数:是solr服务器的访问地址
        // 2、根据指定ID来删除索引
        server.deleteById("c001");
        // 3、提交。 
        server.commit();
    }

(2)根据条件删除索引

代码语言:javascript
复制
    /**
     * 使用solr根据指定条件来删除索引
     * @throws Exception
     */
    @Test
    public void deleteIndexByCondition() throws Exception {
        // 1、创建HttpSolrServer对象,通过它和solr服务器建立连接。 
        HttpSolrServer server = new HttpSolrServer("http://localhost:8080/solr/"); // 参数:是solr服务器的访问地址
        // 2、根据指定条件来删除索引
        server.deleteByQuery("id:c001");
        // 删除全部(慎用)
        // server.deleteByQuery("*:*");
        // 3、提交。 
        server.commit();
    }
4.5.3、查询索引

(1)solr的查询语法

1、q -- 查询关键字,必须的,如果查询所有使用*:*。 请求的q是字符串

2、fq -- (filter query)过滤查询,作用:在q查询符合结果中同时是fq查询符合的,例如:

请求fq是一个数组(多个值)

过滤查询价格从1到20的记录。

也可以在“q”查询条件中使用product_price:1 TO 20,如下:

也可以使用“*”表示无限,例如:

20以上:product_price:20 TO *

20以下:product_price:* TO 20

3.sort -- 排序,格式:sort=[<field name>+<desc|asc>],[<field name>+<desc|asc>],......。示例:

按价格降序

4、start -- 分页显示使用,开始记录下标,从0开始。

5、rows -- 指定返回结果最多有多少条记录,配合start来实现分页。

   实际开发时,知道当前页码和每页显示的个数最后求出开始下标。

6、fl -- 指定返回那些字段内容,用逗号或空格分隔多个。

7、df -- 指定一个默认搜索的field

也可以在solrcore目录中conf/solrconfig.xml文件中指定默认搜索field,指定后就可以直接在“q”查询条件中输入关键字。如下:

8、wt -- (writer type)指定输出格式,可以有xml, json, php, phps,后面是solr 1.3增加的,要用的话需要配置,因为默认没有打开。

9、hl -- 是否高亮,设置高亮field,设置格式前缀和后缀。

(2)简单查询

代码语言:javascript
复制
    /**
     * 简单查询
     * @throws Exception
     */
    @Test
    public void queryIndex01() throws Exception {
        // 1、创建HttpSolrServer对象,通过它和solr服务器建立连接。 
        HttpSolrServer server = new HttpSolrServer("http://localhost:8080/solr/"); // 参数:是solr服务器的访问地址
        // 2、创建SolrQuery对象
        SolrQuery query = new SolrQuery();

        // 设置查询条件,名称"q"是固定的且必须的!
        query.set("q", "product_name:小黄人");

        // 3、调用server的查询方法,查询索引库
        QueryResponse response = server.query(query);
        // 4、获取查询结果
        SolrDocumentList results = response.getResults();
        // 5、处理查询结果
        long count = results.getNumFound();
        System.out.println("查询结果总数为:" + count);
        for (SolrDocument solrDocument : results) {
            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"));
            System.out.println("--------------------");
        }
    }

(3)复杂查询

代码语言:javascript
复制
    /**
     * 复杂查询
     * @throws Exception
     */
    @Test
    public void queryIndex02() throws Exception {
        // 1、创建HttpSolrServer对象,通过它和solr服务器建立连接。 
        HttpSolrServer server = new HttpSolrServer("http://localhost:8080/solr/"); // 参数:是solr服务器的访问地址
        // 2、创建SolrQuery对象
        SolrQuery query = new SolrQuery();

        // 设置查询条件
        // query.set("q", "product_name:小黄人");
        query.setQuery("product_name:小黄人");
        // 设置过滤条件,如果设置多个过滤条件的话,需要使用query.addFilterQuery(fq);
        query.setFilterQueries("product_price:[1 TO 20]");
        // 设置排序
        query.setSort("product_price", ORDER.desc);
        // 设置分页信息(使用默认的)
        query.setStart(0);
        query.setRows(10);
        // 设置显示的field的域集合
        query.setFields("id,product_name,product_catalog,product_price,product_picture");
        // 设置默认域
        query.set("df", "product_keywords");
        // 设置高亮信息
        query.setHighlight(true);
        query.addHighlightField("product_name");
        query.setHighlightSimplePre("<span color='red'>");
        query.setHighlightSimplePost("</span>");

        // 3、调用server的查询方法,查询索引库
        QueryResponse response = server.query(query);
        // 4、获取查询结果
        SolrDocumentList results = response.getResults();
        // 5、处理查询结果
        long count = results.getNumFound();
        System.out.println("查询结果总数为:" + count);

        // 获取高亮列表
        Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();
        for (SolrDocument solrDocument : results) {
            System.out.println(solrDocument.get("id"));

            String productName = (String) solrDocument.get("product_name");
            // 获取本文档的高亮信息
            List<String> list = highlighting.get(solrDocument.get("id")).get("product_name");
            // 如果有高亮信息,则把商品名称赋值为有高亮的那个名称
            if (list != null) {
                productName = list.get(0); // 本例中list只有一条记录
            }
            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"));
            System.out.println("--------------------");
        }
    }

5、京东案例

5.1、需求

使用solr实现电商网站中商品信息搜索功能,可以根据关键字、分类、价格搜索商品信息,也可以根据价格进行排序。

界面如下:

5.2、分析

  开发人员需要的文档:静态页面(根据UI设计由美工给出)、数据库设计、原型设计

5.2.1、UI分析
5.2.2、架构分析

详解如下:

应用服务器服务端:   表现层:使用springmvc接收前台搜索页面的查询条件等信息。   业务层:调用dao层完成数据库持久化。       如果数据库数据发生变化,调用solrj的客户端同步索引库。   Dao层:对商品数据进行维护和查询,使用mybatis完成数据库持久化。 Solrj服务器:   提供搜索和索引服务。 数据库服务器:   提供数据库服务。

5.3、环境准备

  Solr:4.10.3   jdk环境:jdk1.8.0_161(solr4.10 不能使用jdk1.7以下)   ide环境:Eclipse Oxygen   Web服务器(servlet容器):Tomcat 8X

5.4、工程搭建

5.4.1、第一步:创建一个动态的web工程

其中:   1、Dynamic web module version版本选择 2.5,这样兼容性好一些;   2、Default output folder设置为 WebRoot\WEB-INF\classes   3、Content directory设置为 WebRoot 注意:2、3步骤的目的是为了跟MyEclipse兼容,其实不修改也行的。   4、更改JRE System LibraryJ2SE-1.5为 JRE System Libraryjre1.7.0_80   5、删掉没用的库:EAR Libraries   6、增加服务器运行环境库 Server Runtime,不然jsp文件会报错。   7、创建完项目后,将整个项目的编码改为UTF-8。     操作步骤:选中项目右键 --> Properties --> Resource --> Text file encoding --> Other中选择UTF-8。   8、对于动态的java web项目,为了工程目录结构的清爽,我们将引入的jar包放到“Web App Libraries”中,可以通过“小三角”选择是否“Show 'Referenced Libraries' Node ”进行调节。   9、对于普通的java项目,为了工程目录结构的清爽,我们将引入的jar包放到“Referenced Libraries”中,可以通过“小三角”选择是否“Show 'Referenced Libraries' Node ”进行调节。

5.4.2、第二步:添加jar包

  solr服务的扩展包   solr服务的日志包   spring的包(包含springmvc)   jstl包   commons日志包   junit包

5.5、代码实现

5.5.1、pojo

(1)分析索引查询结果

通过分析得出:

  需要一个商品的pojo(Product),存放商品信息。

  还需要一个包装的pojo(ResultModel),它包括商品列表信息、商品分页信息。

(2)相应的代码

Product.java

代码语言:javascript
复制
public class Product {
    // 商品编号
    private String pid;
    // 商品名称
    private String name;
    // 商品分类名称
    private String catalog_name;
    // 价格
    private float price;
    // 商品描述
    private String description;
    // 图片名称
    private String picture;

    // getter和setter
}

ResultModel.java

代码语言:javascript
复制
public class ResultModel {
    // 商品列表
    private List<Product> productList;
    // 商品总数
    private Long recordCount;
    // 总页数
    private int pageCount;
    // 当前页
    private int currentPage;

    // getter和setter
}
5.5.2、dao

功能:

  接收service层传递过来的参数,根据参数查询索引库,返回查询结果给service。

代码语言:javascript
复制
@Repository
public class ProductDaoImpl implements ProductDao {

    // 依赖注入HttpSolrServer
    @Autowired
    private HttpSolrServer server;

    /**
     * 接收service层传递过来的参数,根据参数查询索引库,返回查询结果。
     * 查询商品信息,包括分页信息。
     */
    public ResultModel queryProduct(SolrQuery query) throws Exception {
        ResultModel result = new ResultModel();
        // 通过server查询索引库
        QueryResponse response = server.query(query);
        // 获得查询结果
        SolrDocumentList documentList = response.getResults();

        // 把查询结果的总数设置到ResultModel中去
        result.setRecordCount(documentList.getNumFound());

        List<Product> productList = new ArrayList<Product>();

        Product product = null;
        // 获取高亮信息
        Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();
        for (SolrDocument solrDocument : documentList) {
            product = new Product();
            // 设置商品ID
            product.setPid((String) solrDocument.get("id"));

            // 设置商品名称
            String prodName = (String) solrDocument.get("product_name");
            List<String> list = highlighting.get(solrDocument.get("id")).get("product_name");
            if (list != null) {
                prodName = list.get(0);
            }
            product.setName(prodName);

            // 设置商品分类名称
            product.setCatalog_name((String) solrDocument.get("product_catalog_name"));
            // 设置商品价格
            product.setPrice((Float) solrDocument.get("product_price"));
            // 设置商品图片地址
            product.setPicture((String) solrDocument.get("product_picture"));

            // 把商品添加到商品列表集合中
            productList.add(product);
        }

        // 把商品列表放到ResultMap中
        result.setProductList(productList);

        return result;
    }
}
5.5.3、service

功能:

  接收action传递过来的参数,根据参数拼装一个查询条件,调用dao层方法,查询商品列表。

  接收dao返回的商品列表和商品的总数量,根据每页显示的商品数量计算总页数。

代码语言:javascript
复制
@Service
public class ProductServiceImpl implements ProductService {

    @Autowired
    private ProductDao dao;

    /**
     * 接收action传递过来的参数,根据参数拼装一个查询条件,调用dao层方法,查询商品列表。
     * 接收dao返回的商品列表和商品的总数量,根据每页显示的商品数量计算总页数。
     * @throws Exception 
     */
    public ResultModel queryProduct(String queryString, String catalogName, String price, 
            String sort, Integer currentPage) throws Exception {
        // 创建SolrQuery对象
        SolrQuery query = new SolrQuery();

        // 设置查询条件:输入关键字
        if (queryString != null && !"".equals(queryString)) {
            query.setQuery(queryString);
        } else {
            query.setQuery("*:*");
        }

        // 设置商品类别过滤条件:product_catalog_name:幽默杂货
        if (catalogName != null && !"".equals(catalogName)) {
            query.addFilterQuery("product_catalog_name:" + catalogName);
        }

        // 设置商品价格区间过滤条件:product_price:[10 TO 20]
        if (price != null && !"".equals(price)) {
            // 传过来的price的值:0-9  10-19  20-29
            String[] strings = price.split("-");
            if (strings.length == 2) {
                query.addFilterQuery("product_price:[" + strings[0] + " TO " + strings[1] + "]");
            }
        }

        // 设置排序:传过来1或0,1表示降序,0表示升序。
        if ("1".equals(sort)) {
            query.setSort("product_price", ORDER.desc);
        } else {
            query.setSort("product_price", ORDER.asc);
        }

        // 设置分页信息
        if (currentPage == null) {
            currentPage = 1;
        }
        query.setStart((currentPage - 1) * 20);
        query.setRows(20);

        // 设置默认搜索域
        // query.set("df", "product_keywords");

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

        ResultModel resultModel = dao.queryProduct(query);
        // 设置当前页
        resultModel.setCurrentPage(currentPage);
        // 设置总页数
        Long recordCount = resultModel.getRecordCount();
        int pageCount = (int) (recordCount / 20);
        if (recordCount % 20 > 0) {
            pageCount++;
        }
        resultModel.setPageCount(pageCount);

        return resultModel;
    }
}
5.5.4、controller
代码语言:javascript
复制
@Controller
public class ProductController {

    @Autowired
    private ProductService service;

    @RequestMapping("list")
    public String list(String queryString, String catalog_name, String price, 
            String sort, Integer page, Model model) throws Exception {

        ResultModel resultModel = service.queryProduct(queryString, catalog_name, price, sort, page);
        // 将查询结果放到result域中
        model.addAttribute("result", resultModel);

        // 简单类型的数据回显
        model.addAttribute("queryString", queryString);
        model.addAttribute("caltalog_name", catalog_name);
        model.addAttribute("price", price);
        model.addAttribute("sort", sort);
        model.addAttribute("page", page);
        return "product_list";
    }
}
5.5.5、拷贝jsp文件和静态资源

从以下目录中拷贝

放在项目的如下目录

图片信息放到以下目录

在服务器中进行配置虚拟目录,我们可以通过图形化界面配置,如下:

5.5.6、配置web.xml

web.xml

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
    <display-name>day66_Solr_02_JD</display-name>
    <!-- SpringMVC配置 -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <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>
    <filter>
        <filter-name>characterEncoding</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>characterEncoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>
5.5.7、配置springmvc.xml

在config包下,创建springmvc.xml文件

代码语言:javascript
复制
<?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:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd 
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.1.xsd 
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-3.1.xsd 
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-3.1.xsd ">
    <!-- 配置扫描包 -->
    <context:component-scan base-package="com.itheima" />
    <!-- 配置注解驱动 -->
    <mvc:annotation-driven />
    <!-- jsp视图解析器 -->
    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 前缀 -->
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <!-- 后缀 -->
        <property name="suffix" value=".jsp"></property>
    </bean>
    <!-- 配置solr服务:HttpSolrServer -->
    <bean class="org.apache.solr.client.solrj.impl.HttpSolrServer">
        <constructor-arg value="http://localhost:8080/solr/"></constructor-arg>
    </bean>
</beans>
5.5.8、测试:重新启动Tomcat

访问:http://localhost:8180/day66_Solr_02_JD/list.action

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-11-01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.1、什么是solr
  • 1.2、Solr和Lucene的区别
  • 2、Solr安装和配置(重点)
    • 2.1、下载solr
      • 2.2、solr的运行环境
        • 2.3、初始化数据库脚本
          • 2.4、solrhome和solrcore的安装
            • 2.5、solrcore的配置
              • 2.5.1、lib 标签
              • 2.5.3、requestHandler标签
            • 2.6、启动Tomcat访问solr服务
              • 2.7、solr管理界面功能介绍
                • 2.7.1、Dashboard
                • 2.7.2、Logging
                • 2.7.3、Cloud
                • 2.7.4、Core Admin
                • 2.7.5、Java Properties
                • 2.7.6、Tread Dump
                • 2.7.7、Core selector(重点)
              • 2.8、多个solrcore的配置
              • 3、Solr的基本使用
                • 3.1、schema.xml
                  • 3.1.1、filed(域)
                  • 3.1.2、dynamicField(动态域)
                  • 3.1.3、uniqueKey
                  • 3.1.4、copyField(复制域)
                  • 3.1.5、fieldType(域的类型)
                • 3.2、配置中文分词器
                  • 3.3、配置业务的field
                    • 3.3.1、需求
                    • 3.3.2、定义步骤
                  • 3.4、dataimportHandler插件
                    • 3.4.1、第一步:添加所需的jar包
                    • 3.4.2、第二步:配置solrconfig.xml,添加一个requestHandler
                    • 3.4.3、第三步:创建一个data-config.xml
                    • 3.4.4、第四步:重新启动Tomcat访问solr服务,测试一下
                    • 3.4.5、第五步:点击“Execute”按钮导入数据
                • 4、Solrj的使用
                  • 4.1、什么是solrj
                    • 4.2、需求
                      • 4.3、环境准备
                        • 4.4、工程搭建
                          • 4.5、使用solrj完成索引的维护
                            • 4.5.1、添加\修改索引
                            • 4.5.2、删除索引
                            • 4.5.3、查询索引
                        • 5、京东案例
                          • 5.1、需求
                            • 5.2、分析
                              • 5.2.1、UI分析
                              • 5.2.2、架构分析
                            • 5.3、环境准备
                              • 5.4、工程搭建
                                • 5.4.1、第一步:创建一个动态的web工程
                                • 5.4.2、第二步:添加jar包
                              • 5.5、代码实现
                                • 5.5.1、pojo
                                • 5.5.2、dao
                                • 5.5.3、service
                                • 5.5.4、controller
                                • 5.5.5、拷贝jsp文件和静态资源
                                • 5.5.6、配置web.xml
                                • 5.5.7、配置springmvc.xml
                                • 5.5.8、测试:重新启动Tomcat
                            相关产品与服务
                            容器服务
                            腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                            领券
                            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档