solr服务快速搭建、配置中文分词、数据导入即solrj增删改查

一.准备工作

1. 环境准备:

1.1 centos 6.5/mac os 10.12.6

1.2 solr6.6.0:http://archive.apache.org/dist/lucene/solr/6.6.0/solr-6.6.0.tgz

1.3 IK_Analyzer: https://github.com/SetGeek/ck/blob/master/IK-Analyzer分词器/ik-analyzer-solr6.x.jar

1.4 mysql驱动:https://cdn.mysql.com//Downloads/Connector-J/mysql-connector-java-5.1.44.zip

2. 假定一个需求:现在需要索引商品信息,以支撑前台商品展示页面的搜索。

  1. 数据库中的表有商品分类表和商品详情表
-- 商品表:
DROP TABLE IF EXISTS `rd_product`;
CREATE TABLE `rd_product` (
  `id` varchar(32) NOT NULL COMMENT '商品编号',
  `p_name` varchar(100) NOT NULL COMMENT '商品名称',
  `p_price` decimal(20,2) NOT NULL COMMENT '商品单价',
  `p_amount` int(10) NOT NULL COMMENT '商品数量',
  `p_desc` varchar(1000) DEFAULT NULL COMMENT '商品描述',
  `p_type` varchar(32) DEFAULT NULL COMMENT '商品类型',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--  商品类型表:
DROP TABLE IF EXISTS `rd_type`;
CREATE TABLE `rd_type` (
  `id` varchar(32) NOT NULL COMMENT '类型编号',
  `t_name` varchar(100) NOT NULL COMMENT '类型名称',
  `t_desc` varchar(1000) DEFAULT NULL COMMENT '类型详情',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

二. 搭建standalone模式(单机)的solr服务

1. 安装并启动服务。

​ 解压solr-6.6.0.tgz压缩包,在解压后的文件夹下,使用自带的jetty容器启动solr服务,默认端口为8983,也可以自定义端口启动。

默认启动的命令:bin/solr start

指定端口启动(8080)的命令:bin/solr start -p 8080

服务停止命令:bin/solr stop

2. 查看管理界面。

​ 在浏览器中访问http://localhost:8983/solr,进入solr的管理界面,

3. 创建索引库。

​ 索引存放在索引库中,此时solr中是没有索引库的,需要创建一个索引库,并命名为RD-Core

创建索引库的命令:bin/solr create -c RD-Core

删除索引库的命令:bin/solr delete -c RD-Core

4. 配置中文分词器

如果不需要自定义敏感词汇和行业名词,可以使用solr自带的分词器,否则需要使用IK-Analyzerpaoding等分词器。

4.1 配置solr自带的分词器(选择性配置,也可以都配置上)

4.1.1 引入分词器的jar文件:在server/solr/RD-Product/conf/solrconfig.xml中配置如下信息。

<!-- 引入"contrib/rd-lib/"下所有jar文件 -->
<lib dir="${solr.install.dir:../../../..}/contrib/analysis-extras/lucene-libs/" regex=".*\.jar" />

4.1.2 添加一个中文分词的字段类型(filedType):在solr中,字段类型(fieldType)相当于数据库中的字段类型(intvarchar…),在server/solr/RD-Product/conf/managed-schema中配置如下内容

<fieldType name="text_smartcn" class="solr.TextField" positionIncrementGap="0">
    <!-- 索引时的分词器 -->
    <analyzer type="index">
      <tokenizer class="org.apache.lucene.analysis.cn.smart.HMMChineseTokenizerFactory"/>
    </analyzer>
    <!-- 查询时的分词器 -->
    <analyzer type="query">
       <tokenizer class="org.apache.lucene.analysis.cn.smart.HMMChineseTokenizerFactory"/>
    </analyzer>
</fieldType>
4.2 配置IKAnalyzer分词器

4.2.1 添加分词器的jar文件:在contrib下新建文件夹rd-lib,并将ik-analyzer-solr6.x.jar拷贝进来,这个文件夹用来存放第三方jar文件,后面做数据导入时候,用到的mysql数据库驱动也放到这个文件夹下。

4.2.2 引入分词器的jar文件:在server/solr/RD-Product/conf/solrconfig.xml中配置如下信息,将rd-lib这个文件夹下的所有jar包引入到服务中。

<!-- 引入"contrib/rd-lib/"下所有jar文件 -->
<lib dir="${solr.install.dir:../../../..}/contrib/rd-lib/" regex=".*\.jar" />

4.2.3 添加一个中文分词的字段类型(filedType):在server/solr/RD-Product/conf/managed-schema中配置如下内容

<!--中文分词器IK Analyzer-->
<fieldType name="text_ik" class="solr.TextField">
  <!--索引时候的分词器-->
  <analyzer type="index" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
  <!--查询时候的分词器-->
  <analyzer type="query">
    <tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" isMaxWordLength="false" useSmart="false"/>
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
</fieldType>

4.2.4 自定义敏感词汇与行业专属词汇(如果不需要,可以跳过)

server/solr-webapp/webapp/WEB-INF/下新建一个文件夹classes,并新建文件IKAnalyzer.cfg.xml,内容如下

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">  
<properties>  
    <comment>IK Analyzer 扩展配置</comment>
    <!--用户可以在这里配置自己的扩展字典,'/'表示项目的根路径,多个文件用';'分隔 -->
    <entry key="ext_dict">/ext1.txt;/ext2.txt;</entry> 
    <!--用户可以在这里配置自己的扩展停止词字典-->
    <!-- <entry key="ext_stopwords">stopwords.txt;</entry>  --> 
</properties>

5. 添加需要索引的字段

​ 我们需要索引商品的名称、价格、数量、商品描述、商品类型和商品类型描述,则在文件server/solr/RD-Product/conf/managed-schema中配置如下字段,其中的name是自定义的,不需要与数据库保持一致,type可以是solr内置的数据类型,也可以是上面配置的中文分析器的类型,如果字段包含中文,强烈建议配置为text_smartcntext_ik

<!-- 商品信息 -->
<field name="p_name" type="text_smartcn" indexed="true" stored="true" multiValued="true"/>
<field name="p_price" type="float" indexed="true" stored="true" multiValued="true"/>
<field name="p_amount" type="int" indexed="true" stored="true" multiValued="true"/>
<field name="p_desc" type="text_smartcn" indexed="true" stored="true" multiValued="true"/>
<field name="p_type_name" type="string" indexed="true" stored="true" multiValued="true"/>
<field name="t_desc" type="text_smartcn" indexed="true" stored="true" multiValued="true"/>

6. 配置数据库连接(如果不需要从数据库导入数据,该步骤可以省略)

6.1 引入数据导入的jar包,并添加数据导入处理器,在server/solr/RD-Product/conf/solrconfig.xml中配置
<!-- 导入文件夹dist下所有的jar -->
<lib dir="${solr.install.dir:../../../..}/dist/" regex=".*\.jar" />

<!--数据库导入索引的配置文件 -->
   <requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
    <lst name="defaults">
      <str name="config">data-config.xml</str>
     </lst>
  </requestHandler> 
6.2 在server/solr/RD-Product/conf/中创建data-config.xml,并在其中配置数据库与索引库的连接信息。
<?xml version="1.0" encoding="UTF-8" ?>
<dataConfig>
  <!-- 数据库驱动及数据库信息,数据库:rd_mall,用户名:root,密码为空 -->
  <dataSource type="JdbcDataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://127.0.0.1:3306/rd_mall" user="root" password="" batchSize="-1" />
  <document>
    <entity name="rd_product" query="SELECT p.id AS 'pID',p.p_name AS 'pName',p.p_price AS 'pPrice',p.p_amount AS 'pAmount',p.p_desc AS 'pDesc',t.t_name AS 'pType',t.t_desc AS 't_desc' FROM rd_product p,rd_type t WHERE p.p_type=t.id">
      <!--column的id是数据库的id,name的id是managed_schema里面的id,id是必须,并且唯一的-->
      <field column="pID" name="id" />
      <!--column的pName是数据库的p_name字段,name的p_name是schema-managed中的字段,下面配置同理-->
       <field name="p_name" column="pName"/>
        <field name="p_price" column="pPrice"/>
        <field name="p_amount" column="pAmount"/>
        <field name="p_desc" column="pDesc"/>
        <field name="p_type_name" column="pType"/>
        <field name="t_desc" column="tDesc"/>
    </entity>
  </document>
</dataConfig>
6.3 重启服务后,使用以下命令导入数据,至此,单机版的solr服务搭建完毕。

重启服务:bin/solr restart

导入数据:curl http://localhost:8983/solr/RD-Product/dataimport\?command\=full-import

删除所有数据:bin/post -c RD-Product -d "<delete><query>*:*</query></delete>"

删除指定id的数据:bin/post -c RD-Product -d "<delete><id>p001</id></delete>"

二. SolrJ的使用示例

1.新建一个maven项目,pom.xml如下配置
<?xml version="1.0" encoding="UTF-8"?>
<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>
    <groupId>com.sgcc.gdt.search</groupId>
    <artifactId>rd_solr_demo</artifactId>
    <version>1.0.0</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-solr</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
2.增(改)、删、查及数据库导入数据的使用
public class SearchServer {
    /** solr服务客户端 */
    private SolrClient solrClient;
    /** solr服务的地址 */
    private String solrURL = "http://127.0.0.1:8983/solr";
    /** solr索引库的名称 */
    private String coreName = "RD-Product";

    /**
     * 获取solr服务的客户端
     */
    @Before
    public void init() {
        solrClient = new HttpSolrClient("http://127.0.0.1:8983/solr");
    }

    /**
     * 关闭solr服务
     */
    @After
    public void destroy() throws IOException {
        if (solrClient != null) {
            solrClient.close();
        }
    }

    /**
     * 查询示例
     */
    @Test
    public void queryTest() throws IOException, SolrServerException {
        //查询条件
        SolrQuery solrQuery = new SolrQuery();
        solrQuery.setQuery("*:*");
        //查询方法
        QueryResponse response = solrClient.query(coreName, solrQuery);
        SolrDocumentList results = response.getResults();
        System.out.println("查询结果:" + response);
    }

    /**
     * 添加索引
     */
    @Test
    public void add() throws IOException, SolrServerException {
        //构造索引文档
        SolrInputDocument document = new SolrInputDocument();
        String id = UUID.randomUUID().toString().replaceAll("-", "");
        document.setField("id", id);
        document.setField("p_name", "神州笔记本电脑");
        document.setField("p_price", 1234f);
        document.setField("p_amount", 100);
        document.setField("p_type_name", "电脑");

        //添加索引文档
        solrClient.add(coreName, document);
        solrClient.commit(coreName);
        System.out.println("添加成功!");
    }

    /**
     * 删除索引
     */
    @Test
    public void delete() throws IOException, SolrServerException {
        solrClient.deleteByQuery(coreName, "*:*");
        System.out.println("删除成功!");
    }

    /**
     * 从数据库导入索引
     */
    @Test
    public void dataImportTest() throws IOException {
        String path1 = "http://localhost:8983/solr/RD-Product/dataimport?command=full-import";
        RequestConfig config = RequestConfig.custom().setConnectTimeout(60000).setSocketTimeout(15000).build();
        HttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config).build();
        HttpGet httpGet = new HttpGet(path1);
        HttpResponse response = httpClient.execute(httpGet);
        int statusCode = response.getStatusLine().getStatusCode();
        if(statusCode == HttpStatus.SC_OK){
            httpGet.abort();
            System.out.println("导入数据成功!");
        }
    }
}

本示例中出现的问题,欢迎指正,共同学习!
GitHub地址:https://github.com/SetGeek/ck.git
本人邮箱: yangchaokai@foxmail.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值