为了账号安全,请及时绑定邮箱和手机立即绑定

day73_淘淘商城项目_06_solr索引库搭建 + solr搜索功能实现 + 图片显示等问题解一决

标签:
深度学习

 

1、搜索工程的搭建

https://img1.sycdn.imooc.com//5bf672b30001d37d10590677.jpg
要实现搜索功能,需要搭建solr服务搜索服务工程搜索系统(表现层的工程)

1.1、Solr服务搭建

1.1.1、solr的环境

  solr是java开发的。
  solr的安装文件。
  推荐在Linux环境下使用Solr,需要安装环境Linux。
  需要安装jdk。参考链接:https://www.cnblogs.com/chenmingjun/p/9931593.html
  需要安装tomcat。

1.1.2、solr的搭建步骤

第一步:使用SecureCRT的SFTP功能,把solr-4.10.3.tgz.tgz的压缩包上传到Linux系统。
第二步:解压缩solr后,删除该安装包。

[root@itheima ~]# tar -zxvf solr-4.10.3.tgz.tgz
......
......
[root@itheima ~]# ll
总用量 146496
drwxr-xr-x. 8 root root       218 11月 20 17:07 solr-4.10.3
-rw-r--r--. 1 root root 150010621 9月  26 23:16 solr-4.10.3.tgz.tgz
[root@itheima ~]# rm -rf solr-4.10.3.tgz.tgz
[root@itheima ~]# ll
总用量 0
drwxr-xr-x. 8 root root 218 11月 20 17:07 solr-4.10.3
[root@itheima ~]# 

第三步:使用SecureCRT的SFTP功能,把apache-tomcat-7.0.47.tar.gz的压缩包上传到Linux系统,解压后删除安装包。

[root@itheima ~]# tar -zxvf apache-tomcat-7.0.47.tar.gz
[root@itheima ~]# # rm -rf apache-tomcat-7.0.47.tar.gz

第四步:创建solr存放的目录,复制apache-tomcat-7.0.47目录/usr/local/solr/tomcat目录

[root@itheima ~]# mkdir /usr/local/solr
[root@itheima ~]# cp -r apache-tomcat-7.0.47/ /usr/local/solr/tomcat

第五步:把solr-4.10.3/dist/solr-4.10.3.war文件部署(复制)到tomcat目录下,并重命名为solr.war

[root@itheima ~]# cp solr-4.10.3/dist/solr-4.10.3.war /usr/local/solr/tomcat/webapps/solr.war

注意:复制目录(文件夹)的时候需要加-r,复制文件的时候不需要加-r
第六步:解压缩solr.war包。启动tomcat即可自动解压war包,并查看tomcat启动日志

[root@itheima ~]# cd /usr/local/solr/tomcat/bin/
[root@itheima bin]# ./startup.sh 
Using CATALINA_BASE:   /usr/local/solr/tomcat
Using CATALINA_HOME:   /usr/local/solr/tomcat
Using CATALINA_TMPDIR: /usr/local/solr/tomcat/temp
Using JRE_HOME:        /usr/local/java/jdk1.7.0_80/jre
Using CLASSPATH:       /usr/local/solr/tomcat/bin/bootstrap.jar:/usr/local/solr/tomcat/bin/tomcat-juli.jar
[root@itheima bin]# cd ..
[root@itheima tomcat]# tail -f logs/catalina.out
十一月 20, 2018 5:23:24 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deploying web application directory /usr/local/solr/tomcat/webapps/host-manager
十一月 20, 2018 5:23:25 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deploying web application directory /usr/local/solr/tomcat/webapps/manager
十一月 20, 2018 5:23:25 下午 org.apache.coyote.AbstractProtocol start
信息: Starting ProtocolHandler ["http-bio-8080"]
十一月 20, 2018 5:23:25 下午 org.apache.coyote.AbstractProtocol start
信息: Starting ProtocolHandler ["ajp-bio-8009"]
十一月 20, 2018 5:23:25 下午 org.apache.catalina.startup.Catalina start
信息: Server startup in 11144 ms

第六步:关闭tomcat后,删除掉没用的solr.war包。原则:没用的东西及时删掉。
注意:要是想删掉没用的solr.war包,必须在关闭tomcat的情况下,否则解压缩后的solr包也会一并删除掉。

[root@itheima tomcat]# bin/shutdown.sh 
Using CATALINA_BASE:   /usr/local/solr/tomcat
Using CATALINA_HOME:   /usr/local/solr/tomcat
Using CATALINA_TMPDIR: /usr/local/solr/tomcat/temp
Using JRE_HOME:        /usr/local/java/jdk1.7.0_80/jre
Using CLASSPATH:       /usr/local/solr/tomcat/bin/bootstrap.jar:/usr/local/solr/tomcat/bin/tomcat-juli.jar
[root@itheima tomcat]# rm -rf webapps/solr.war 

第七步:想要启动solr工程,还需要添加solr的扩展服务包
/root/solr-4.10.3/example/lib/ext目录下的所有的jar包,添加到solr工程中。

[root@itheima ext]# pwd
/root/solr-4.10.3/example/lib/ext
[root@itheima ext]# cp * /usr/local/solr/tomcat/webapps/solr/WEB-INF/lib/

第八步:创建一个solrhome目录。
我们知道:/root/solr-4.10.3/example/solr目录就是一个solrhome目录。
复制此目录中所有内容到/usr/local/solr/solrhome目录下

[root@itheima example]# pwd
/root/solr-4.10.3/example
[root@itheima example]# cp -r solr /usr/local/solr/solrhome

第九步:关联solr工程solrhome。需要修改solr工程web.xml文件。

[root@itheima ~]# cd /usr/local/solr/tomcat/webapps/solr/WEB-INF/
[root@itheima WEB-INF]# vim web.xml

修改如下图所示:

https://img1.sycdn.imooc.com//5bf672be000152e908000127.jpg
第九步:再次启动tomcat

[root@itheima ~]# cd /usr/local/solr/tomcat/
[root@itheima tomcat]# bin/startup.sh 

第十步:修改防火墙配置
CentOS 7.X 默认的防火墙不是iptables,而是firewalld。我们可以试一下systemctl stop firewalld关闭防火墙,但是不推荐该方式。
CentOS 6.X 是iptables,可以使用vim /etc/sysconfig/iptables修改配置即可。
本博主的是CentOS7,防火墙使用的是firewalld,我们使用命令的方式来添加端口(修改后需要重启firewalld服务):

[root@itheima ~]# cd /etc/firewalld/zones/
[root@itheima zones]# firewall-cmd --permanent --add-port=8080/tcp
success
[root@itheima zones]# service firewalld restart
Redirecting to /bin/systemctl restart firewalld.service
[root@itheima zones]#

第十一步:测试连接
访问地址:http://192.168.25.154:8080/solr/
其实和在windows下的配置完全一样。
浏览器界面如下:

https://img1.sycdn.imooc.com//5bf672d900019a9713270782.jpg
点击按钮“collection1”
https://img1.sycdn.imooc.com//5bf672e000012a1613270782.jpg

1.1.3、solr的使用

  • 添加文档时必须有id域,其他域必须在solr的schema.xml中进行定义。

1.2、配置业务域

1.2.1、在schema.xml中需要定义以下字段

  1、商品id(根据id查询商品描述页)
  2、商品标题title
  3、商品卖点sell_point
  4、商品价格price
  5、商品图片image
  6、分类名称category_name(不是分类id,我们一般不会根据商品分类id去查询商品,而是根据商品分类名称去查)
  7、商品描述item_desc(实际开发中不需要搜索商品描述)
  一共涉及到三张表:tb_item、item_cat、item_desc。
  创建对应的业务域。同时需要指定中文分析器。

1.2.2、创建业务域步骤

第一步:把中文分析器添加到solr工程中。
  0、把文件夹IK Analyzer 2012FF_hf1上传至linux中。
  1、把IKAnalyzer2012FF_u1.jar拷贝到solr工程的lib目录下。
  2、把扩展词词典停用词字典配置文件拷贝到solr工程的WEB-INF/classes目录下。(没有classes目录就先创建该目录)

[root@itheima IK Analyzer 2012FF_hf1]# pwd
/root/IK Analyzer 2012FF_hf1
[root@itheima IK Analyzer 2012FF_hf1]# cp IKAnalyzer2012FF_u1.jar /usr/local/solr/tomcat/webapps/solr/WEB-INF/lib/
[root@itheima IK Analyzer 2012FF_hf1]# mkdir /usr/local/solr/tomcat/webapps/solr/WEB-INF/classes
[root@itheima IK Analyzer 2012FF_hf1]# cp mydict.dic ext_stopword.dic IKAnalyzer.cfg.xml /usr/local/solr/tomcat/webapps/solr/WEB-INF/classes
[root@itheima IK Analyzer 2012FF_hf1]# ll /usr/local/solr/tomcat/webapps/solr/WEB-INF/classes
总用量 12
-rw-r--r--. 1 root root 168 11月 20 19:29 ext_stopword.dic
-rw-r--r--. 1 root root 419 11月 20 19:29 IKAnalyzer.cfg.xml
-rw-r--r--. 1 root root  34 11月 20 19:29 mydict.dic
[root@itheima IK Analyzer 2012FF_hf1]# 

第二步:配置一个自定义的fieldType,使用指定的中文分词器IKAnalyzer
  修改solr工程下的schema.xml文件,在文件末尾添加一个自定义的fieldType,注意:要在标签<schema></schema>里面添加。

[root@itheima conf]# pwd
/usr/local/solr/solrhome/collection1/conf
[root@itheima conf]# vim schema.xml

  添加内容如下:

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

第三步:配置业务域,type指定使用自定义的fieldType。
  设置业务系统的field

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

      <field name="item_title" type="text_ik" indexed="true" stored="true"/>
      <field name="item_sell_point" type="text_ik" indexed="true" stored="true"/>
      <field name="item_price" type="long" indexed="true" stored="true"/>
      <field name="item_image" type="string" indexed="false" stored="true"/>
      <field name="item_category_name" type="string" indexed="true" stored="true"/>
      <field name="item_desc" type="text_ik" indexed="true" stored="false"/>

    <!-- 复制域 -->
    <field name="item_keywords" type="text_ik" indexed="true" stored="false" multiValued="true"/>
      <copyField source="item_title" dest="item_keywords"/>
      <copyField source="item_sell_point" dest="item_keywords"/>
      <copyField source="item_category_name" dest="item_keywords"/>
      <copyField source="item_desc" dest="item_keywords"/>
</schema>

  注意:分类名称是不分词只建立索引。商品描述是分词但是不存储。

第四步:重启tomcat,测试我们自定义的业务域是否好使。
测试结果如下:

https://img1.sycdn.imooc.com//5bf672eb00012eeb12630735.jpg

1.3、搜索服务层工程的搭建

1.3.1、搜索服务工程的创建可以参考taotao-content的创建

taotao-search(聚合工程pom)
  |--taotao-search-interface(jar)
  |--taotao-search-Service(war)
这里不再赘图了。
目录结构如下:

https://img1.sycdn.imooc.com//5bf6730f0001dd5801900067.jpg

1.3.2、pom.xml的配置可以参考taotao-content的配置

/taotao-search/pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
    http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.taotao</groupId>
        <artifactId>taotao-parent</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>taotao-search</artifactId>
    <packaging>pom</packaging>
    <modules>
        <module>taotao-search-interface</module>
        <module>taotao-search-service</module>
    </modules>
    <dependencies>
        <!-- 配置对common的依赖 -->
        <dependency>
            <groupId>com.taotao</groupId>
            <artifactId>taotao-common</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <!-- 配置Tomcat插件  -->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <configuration>
                    <port>8085</port>
                    <path>/</path>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

/taotao-search-interface/pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
    http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.taotao</groupId>
        <artifactId>taotao-search</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>taotao-search-interface</artifactId>
    <dependencies>
        <!-- 配置对pojo的依赖 -->
        <dependency>
            <groupId>com.taotao</groupId>
            <artifactId>taotao-manager-pojo</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>

/taotao-search-service/pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
    http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.taotao</groupId>
        <artifactId>taotao-search</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>taotao-search-service</artifactId>
    <packaging>war</packaging>
    <dependencies>
        <!-- 配置对dao的依赖 -->
        <dependency>
            <groupId>com.taotao</groupId>
            <artifactId>taotao-manager-dao</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <!-- 配置对interface的依赖:服务层发布服务要通过该接口 -->
        <dependency>
            <groupId>com.taotao</groupId>
            <artifactId>taotao-search-interface</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <!-- 配置对spring的依赖 -->
        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jms</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>
        <!-- 配置对dubbo的依赖 -->
        <!-- dubbo相关 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <!-- 排除对低版本jar包的依赖 -->
            <exclusions>
                <exclusion>
                    <artifactId>spring</artifactId>
                    <groupId>org.springframework</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>netty</artifactId>
                    <groupId>org.jboss.netty</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
        </dependency>
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
        </dependency>
    </dependencies>
</project>

1.3.3、框架整合的配置文件可以参考taotao-content-service的配置

https://img1.sycdn.imooc.com//5bf6731d0001f60b06420562.jpg
由于搜索的数据涉及到3张表,所以需要自己定义mapper。
而mapper的使用,只在搜索服务工程中,所以mapper接口及映射文件需要放在taotao-search-service工程中。
applicationContext-dao.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-4.2.xsd
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop-4.2.xsd 
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
    http://www.springframework.org/schema/util 
    http://www.springframework.org/schema/util/spring-util-4.2.xsd">
    <!-- 配置数据库连接池 -->
    <!-- 加载配置文件 -->
    <context:property-placeholder location="classpath:properties/*.properties" />
    <!-- 数据库连接池 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
        destroy-method="close">
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="maxActive" value="10" />
        <property name="minIdle" value="5" />
    </bean> 
    <!-- 配置让spring管理sqlsessionfactory,使用mybatis和spring整合包中的 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 数据库连接池 -->
        <property name="dataSource" ref="dataSource" />
        <!-- 加载mybatis的全局配置文件 -->
        <property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml" />
    </bean> 
    <!-- 配置Mapper映射文件的包扫描器 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.taotao.mapper" />
    </bean>
</beans>

其他配置文件,参考taotao-content-service的配置。

回到顶部

2、测试使用solrJ管理索引库

使用solrJ可以实现索引库的增删改查操作。

2.1、通过SolrJ向索引库中添加/更新索引

第一步:把solrJ的jar包添加到工程中。在Maven工程中则是添加依赖。
在/taotao-search-service/pom.xml添加对solrj客户端的依赖,如下:

    <!-- 配置对solrj客户端的依赖 -->
    <dependency>
        <groupId>org.apache.solr</groupId>
        <artifactId>solr-solrj</artifactId>
    </dependency>

第二步:创建一个SolrServer对象(抽象类),使用HttpSolrServer创建对象(连接单机版solr),使用CloudSolrServer创建对象(连接集群版solr)。
第三步:创建一个文档对象SolrInputDocument对象。
第四步:向文档中添加域。必须有id域,且域的名称必须在schema.xml中定义。
第五步:把文档对象添加到索引库中。
第六步:提交。
测试代码如下:

    /**
     * 向索引库中添加索引
     * @throws Exception
     */
    @Test
    public void addDocumentTest() throws Exception {
        // 第一步:把solrJ的jar包添加到工程中。在Maven工程中则是添加依赖。
        // 第二步:创建一个SolrServer对象(抽象类),使用HttpSolrServer创建连接对象(连接单机版solr),使用CloudSolrServer创建连接对象(连接集群版solr)。
        SolrServer solrServer = new HttpSolrServer("http://192.168.25.154:8080/solr/collection1"); // 默认是collection1,可写可不写
        // 第三步:创建一个文档对象SolrInputDocument对象。
        SolrInputDocument document = new SolrInputDocument();
        // 第四步:向文档中添加域。必须有id域,且域的名称必须在schema.xml中定义。
        document.addField("id", "test001"); // 注意:id是字符串类型,如果是数值类型,会自动转为字符串
        document.addField("item_title", "测试商品");
        document.addField("item_price", 1999);
        // 第五步:把文档对象添加到索引库中。
        solrServer.add(document);
        // 第六步:提交。
        solrServer.commit();
    }

2.2、通过SolrJ从索引库中删除索引

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

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

(2)根据指定条件删除索引

    /**
     * 根据指定条件来删除索引
     * @throws Exception
     */
    @Test
    public void deleteIndexByConditionTest() throws Exception {
        // 1、创建HttpSolrServer对象,通过它和solr服务器建立连接。 
        HttpSolrServer server = new HttpSolrServer("http://192.168.25.154:8080/solr/collection1"); // 参数:是solr服务器的访问地址
        // 2、根据指定条件来删除索引
        server.deleteByQuery("id:test002");
        // 删除全部(慎用)
        // server.deleteByQuery("*:*");
        // 3、提交。 
        server.commit();
    }

2.3、通过SolrJ从索引库中查询索引

2.3.1、简单查询

    /**
     * 简单查询
     * @throws Exception
     */
    @Test
    public void queryIndexTest01() throws Exception {
        // 1、创建SolrServer对象,通过它和solr服务器建立连接。 
        SolrServer solrServer = new HttpSolrServer("http://192.168.25.154:8080/solr/collection1"); // 参数:是solr服务器的访问地址
        // 2、创建SolrQuery对象
        SolrQuery query = new SolrQuery();

        // 设置查询条件,名称"q"是固定的且必须的!
        // query.set("q", "item_category_name:手机"); // 等价于    query.setQuery("item_category_name:手机");
        query.setQuery("item_category_name:手机");
        // 3、调用solrServer的查询方法,查询索引库
        QueryResponse response = solrServer.query(query);
        // 4、获取查询结果
        SolrDocumentList results = response.getResults();
        // 5、处理查询结果
        System.out.println("查询结果总数为:" + results.getNumFound());
        // 6、遍历结果并打印,示例只打印2个字段
        for (SolrDocument solrDocument : results) {
            System.out.println(solrDocument.get("id"));
            System.out.println(solrDocument.get("item_title"));
            System.out.println(solrDocument.get("item_price"));
            System.out.println("--------------------");
        }
    }

2.3.2、复杂查询

   /**
     * 复杂查询
     * @throws Exception
     */
    @Test
    public void queryIndexTest02() throws Exception {
        // 1、创建SolrServer对象,通过它和solr服务器建立连接。 
        SolrServer solrServer = new HttpSolrServer("http://192.168.25.154:8080/solr/collection1"); // 参数:是solr服务器的访问地址
        // 2、创建SolrQuery对象
        SolrQuery query = new SolrQuery();

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

        // 3、调用solrServer的查询方法,查询索引库
        QueryResponse response = solrServer.query(query);
        // 4、获取查询结果
        SolrDocumentList results = response.getResults();

        // 5、处理查询结果
        System.out.println("查询结果总数为:" + results.getNumFound());

        // 获取高亮列表
        Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();
        // 遍历结果并打印,示例打印所有的字段
        for (SolrDocument solrDocument : results) {
            System.out.println(solrDocument.get("id"));

            List<String> list = highlighting.get(solrDocument.get("id")).get("item_title");
            String itemTitle = null;
            if (list != null && list.size() > 0) {
                itemTitle = list.get(0);
            } else {
                itemTitle = (String) solrDocument.get("item_title");
            }
            System.out.println(itemTitle);

            System.out.println(solrDocument.get("item_sell_point"));
            System.out.println(solrDocument.get("item_price"));
            System.out.println(solrDocument.get("item_image"));
            System.out.println(solrDocument.get("item_category_name"));
            System.out.println("--------------------");
        }
    }

回到顶部

3、把商品数据导入到索引库中(后台功能)

3.1、功能分析

在schema.xml中定义以下业务域(已经定义好):

    1、商品id(根据id查询商品描述页)
    2、商品标题title
    3、商品卖点sell_point
    4、商品价格price
    5、商品图片image
    6、分类名称category_name(不是分类id,我们一般不会根据商品分类id去查询商品,而是根据商品分类名称去查)
    7、商品描述item_desc(实际开发中不需要搜索商品描述)

需要从 tb_item、tb_item_cat、tb_item_desc表中查询数据。
我们先创建对应的业务域(已经创建好了)。同时需要指定中文分析器。

  solr服务我们已经搭建好了,自定义的业务域我们也配置好了,现在我们要实现商品搜素功能,那么就需要有数据,需要把数据从数据库中导入进来,之前我们可以使用dataimportHandler插件,该插件可以将数据库中指定的sql语句的结果导入到solr索引库中。现在我们需要通过我们网站后台来管理索引库,而不是通过dataimportHandler插件了,而且我们要做solr集群的话,插件dataimportHandler会有干扰。所以我们现在不推荐使用dataimportHandler插件。
  所以我们在测试环境下可以使用dataimportHandler插件,但是生产环境下需要我们手工导入数据。
  插件dataimportHandler,使用参考链接:https://www.cnblogs.com/chenmingjun/p/9887696.html#_label2_3
  我们使用手工导入数据,需要我们先从数据库中把我们分析出来的业务域取出来,取出来之后,循环插入索引库中去,由于涉及到3张表的查询,所以不能在使用逆向工程生成的Mapper代码了。需要我们手写Mapper代码。我们先把SQL语句写出来,如下:
SQL1:

SELECT
    a.id,
    a.title,
    a.sell_point,
    a.price,
    a.image,
    b. NAME AS category_name,
    c.item_desc
FROM
    tb_item a
LEFT JOIN tb_item_cat b ON a.cid = b.id
LEFT JOIN tb_item_desc c ON a.id = c.item_id
WHERE
    a.`status` = 1

SQL2:

SELECT
    a.id,
    a.title,
    a.sell_point,
    a.price,
    a.image,
    b. NAME AS category_name,
    c.item_desc
FROM
    tb_item a,
    tb_item_cat b,
    tb_item_desc c
WHERE
    a.cid = b.id
AND a.id = c.item_id
AND a.`status` = 1;

3.2、Dao层

3.2.1、创建POJO

创建以下POJO用于存放从数据库中查询到的商品数据和用于存放从索引库中搜索到的商品数据,并放入taotao-common中。

/**
 * 搜索商品数据使用的POJO,用于存放“从数据库中查询到的商品数据”和用于存放“从索引库中搜索到的商品数据”
 * @author chenmingjun
 * @date 2018年11月21日上午1:05:12
 * @version 1.0
 */
public class SearchItem implements Serializable {

    private static final long serialVersionUID = 1L;

    private String id; // 商品的id,我们使用文档的id域作为商品的id,文档的id域默认定义的是String类型
    private String title; // 商品的标题
    private String sell_point; // 商品的卖点
    private Long price; // 商品的价格
    private String image; // 商品的图片路径
    private String category_name; // 商品的分类名称
    private String item_desc; // 商品的描述

    // getter和setter方法
}

注意:在我们schema.xml文件中,我们使用文档的id域作为商品的id,而文档的id域默认定义的是String类型,索引库会自动转换将数值类型转换为字符串进行存储,我们从索引库中取出数据,我们也使用字符串进行接收。

3.2.2、定义Mapper接口

SearchItemMapper.java

/**
 * 搜索商品的Mapper
 * @author    chenmingjun
 * @date    2018年11月21日上午11:23:28
 * @version 1.0
 */
public interface SearchItemMapper {

    /**
     * 查询所有商品数据。(注意:是从3张表中查,此商品非彼商品)
     * @return
     */
    List<SearchItem> getSearchItemList();
}

3.2.3、编写Mapper映射文件

SearchItemMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.taotao.search.mapper.SearchItemMapper" >
    <select id="getSearchItemList" resultType="com.taotao.common.pojo.SearchItem">
        SELECT
            a.id,
            a.title,
            a.sell_point,
            a.price,
            a.image,
            b. NAME AS category_name,
            c.item_desc
        FROM
            tb_item a
        LEFT JOIN tb_item_cat b ON a.cid = b.id
        LEFT JOIN tb_item_desc c ON a.id = c.item_id
        WHERE
            a.`status` = 1  
    </select>
</mapper>

3.3、Service层

参数:无
业务逻辑:
  1、查询所有商品数据。
  2、创建一个SolrServer对象(抽象类),使用HttpSolrServer创建连接对象(连接单机版solr),使用CloudSolrServer创建连接对象(连接集群版solr)。
  3、为每个商品创建一个文档对象SolrInputDocument对象。
  4、为文档添加域。必须有id域,且域的名称必须在schema.xml中定义。
  5、把文档对象添加到索引库中。
  6、提交修改。
  7、返回TaotaoResult。

3.3.1、配置单机版solr的连接:HttpSolrServer

SolrServer我们使用spring容器生成后注入进来,需要在配置文件进行配置:
applicationContext-solr.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-4.2.xsd
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop-4.2.xsd 
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
    http://www.springframework.org/schema/util 
    http://www.springframework.org/schema/util/spring-util-4.2.xsd">

    <!-- 配置单机版solr的连接:HttpSolrServer-->
    <bean id="httpSolrServer" class="org.apache.solr.client.solrj.impl.HttpSolrServer">
        <constructor-arg name="baseURL" value="http://192.168.25.154:8080/solr/collection1"></constructor-arg>
    </bean>
</beans>

3.3.2、定义service接口

接口放在taotao-search-interface中

/**
 * 从数据库中查询到数据导入索引库
 * @author    chenmingjun
 * @date    2018年11月21日下午2:38:41
 * @version 1.0
 */
public interface SearchItemService {

    /**
     * 导入搜索的商品数据到索引库中
     * @return
     * @throws Exception
     */
    TaotaoResult importSearchItemsToIndex() throws Exception;
}

3.3.3、定义service实现类

要想注入SearchItemMapper成功,需要在taotao-search-serviceapplicationContext-dao.xml文件中进行配置Mapper映射文件的包扫描器
有两种配置方式:
方式一:

    <!-- 配置Mapper映射文件的包扫描器 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.taotao.mapper" />
    </bean>
    <!-- 配置只用于搜索功能的Mapper -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.taotao.search.mapper" />
    </bean>

方式二:

    <!-- 配置Mapper映射文件的包扫描器,扫描多个包,使用逗号进行分割 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.taotao.mapper,com.taotao.search.mapper" />
    </bean>

本案例中我们使用方式二。
实现类代码如下:

/**
 * 从数据库中查询到数据导入索引库
 * @author    chenmingjun
 * @date    2018年11月21日下午2:42:11
 * @version 1.0
 */
@Service
public class SearchItemServiceImpl implements SearchItemService {

    // 注入SearchItemMapper
    @Autowired
    private SearchItemMapper searchItemMapper;

    // 注入SolrServer
    @Autowired
    private SolrServer solrServer;

    @Override
    public TaotaoResult importSearchItemsToIndex() throws Exception {
        // 1、查询所有商品数据。 
        List<SearchItem> searchItemList = searchItemMapper.getSearchItemList();
        // 2、创建一个SolrServer对象(抽象类),使用HttpSolrServer创建连接对象(连接单机版solr),使用CloudSolrServer创建连接对象(连接集群版solr)。 
        // SolrServer我们使用spring容器生成后注入进来
        for (SearchItem searchItem : searchItemList) {
            // 3、为每个商品创建一个文档对象SolrInputDocument对象。 
            SolrInputDocument document = new SolrInputDocument();
            // 4、为文档添加域。必须有id域,且域的名称必须在schema.xml中定义。 
            document.addField("id", searchItem.getId());
            document.addField("item_title", searchItem.getTitle());
            document.addField("item_sell_point", searchItem.getSell_point());
            document.addField("item_price", searchItem.getPrice());
            document.addField("item_image", searchItem.getImage());
            document.addField("item_category_name", searchItem.getCategory_name());
            document.addField("item_desc", searchItem.getItem_desc());
            // 5、把文档对象添加到索引库中。 
            solrServer.add(document);
        }
        // 6、提交修改。
        solrServer.commit();
        // 7、返回TaotaoResult。
        return TaotaoResult.ok();
    }
}

3.3.4、在taotao-search-service中发布服务

https://img1.sycdn.imooc.com//5bf673b800015b2d11540253.jpg
特别注意:由于我们的dubbo和zooKeeper是安装在虚拟机CentOS 7.5 上的,CentOS 7.X 默认的防火墙不是iptables,而是firewalld。我们可以试一下systemctl stop firewalld关闭防火墙,但是不推荐该方式。CentOS 6.X 是iptables,可以使用vim /etc/sysconfig/iptables修改配置即可。
本博主的是CentOS7,防火墙使用的是firewalld,我们使用命令的方式来添加端口20882(修改后需要重启firewalld服务):

[root@itheima ~]# cd /etc/firewalld/zones/
[root@itheima zones]# firewall-cmd --permanent --add-port=20882/tcp
success
[root@itheima zones]# service firewalld restart
Redirecting to /bin/systemctl restart firewalld.service
[root@itheima zones]#

3.4、表现层

3.4.1、引用服务

由于把从数据库中查询到的新的商品数据导入到索引库中属于后台功能,所以我们在taotao-manager-web中引用服务。
在/taotao-manager-web/src/main/resources/spring/springmvc.xml中引用服务:

https://img1.sycdn.imooc.com//5bf673c10001b44410980183.jpg

3.4.2、添加对taotao-search-interface的依赖

在taotao-manager-web工程中的pom.xml中添加如下:

https://img1.sycdn.imooc.com//5bf673d40001de4b06670736.jpg

原文出处:https://www.cnblogs.com/chenmingjun/p/10002204.html  


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消