Solr7.1 学习笔记

一、Lucene介绍

1. lucene简介

Lucene是一个全文搜索框架,而不是应用产品。因此它并不像 baidu 或者google Desktop那么拿来就能用,它只是提供了一种工具让你能实现这些产品。

在全文检索工具中,全部都由三个部分组成:索引部分、分词部分、搜索部分


2. lucene的工作方式

lucene提供的服务实际包含两部分:一入一出。所谓入是写入,即将你提供的源(本质是字符串)写入索引或者将其从索引中删除;所谓出是读出,即向用户提供全文搜索服务,让用户可以通过关键词定位源。

2.1 写入流程

源字符串首先经过analyzer处理,包括:分词,分成一个个单词;去除stopword(可选)。将源中需要的信息加入Document的各个Field中,并把需要索引的Field索引起来,把需要存储的Field存储起来。 将索引写入存储器,存储器可以是内存或磁盘。

2.2 读出流程

用户提供搜索关键词,经过analyzer处理。对处理后的关键词搜索索引找出对应的Document。用户根据需要从找到的Document中提取需要的Field。


3. 关键名词解释

3.1 analyzer

Analyzer是分析器(分词器),它的作用是把一个字符串按某种规则划分成一个个词语,并去除其中的无效词语,这里说的无效词语是指英文中的“of”、“the”,中文中的“的”、“地”等词语,这些词语在文章中大量出现,但是本身不包含什么关键信息,去掉有利于缩小索引文件、提高效率、提高命中率。分词的规则千变万化,但目的只有一个:按语义划分。这点在英文中比较容易实现,因为英文本身就是以单词为单位的,已经用空格分开;而中文则必须以某种方法将连成一片的句子划分成一个个词语

3.2 document

用户提供的源是一条条记录,它们可以是文本文件、字符串或者数据库表的一条记录等等。一条记录经过索引之后,就是以一个Document的形式存储在索引文件中的。用户进行搜索,也是以Document列表的形式返回。

3.3 field

一个Document可以包含多个信息域,例如一篇文章可以包含“标题”、“正文”、“最后修改时间”等信息域,这些信息域就是通过FieldDocument中存储的。Field有两个属性可选:存储索引。通过存储属性你可以控制是否对这个Field进行存储;通过索引属性你可以控制是否对该Field进行索引。这看起来似乎有些废话,事实上对这两个属性的正确组合很重要,下面举例说明:还是以刚才的文章为例子,我们需要对标题和正文进行全文搜索,所以我们要把索引属性设置为真,同时我们希望能直接从搜索结果中提取文章标题,所以我们把标题域的存储属性设置为真,但是由于正文域太大了,我们为了缩小索引文件大小,将正文域的存储属性设置为假,当需要时再直接读取文件;我们只是希望能从搜索解果中提取最后修改时间,不需要对它进行搜索,所以我们把最后修改时间域的存储属性设置为真,索引属性设置为假。上面的三个域涵盖了两个属性的三种组合,还有一种全为假的没有用到,事实上Field不允许你那么设置,因为既不存储又不索引的域是没有意义的。

3.4 term

term是搜索的最小单位,它表示文档的一个词语,term由两部分组成:它表示的词语和这个词语所出现的field

3.5 tocken

Token是一种在对文本进行分词时产生的对象,包含分词对象(Term)的词语内容,词语在文本中的开始结束位置,和一个词语类型(关键字、停用词)字符串。
开始结束位置这两个参数,可以在做文本高亮或者摘要高亮的时候使用。

3.6 segment

添加索引时并不是每个document都马上添加到同一个索引文件,它们首先被写入到不同的小文件,然后再合并成一个大索引文件,这里每个小文件都是一个segment


4. 性能

下面给出一些测试数据,如果你觉得可以接受,那么可以选择。
测试一:250万记录,300M左右文本,生成索引380M左右,800线程下平均处理时间300ms。
测试二:37000记录,索引数据库中的两个varchar字段,索引文件2.6M,800线程下平均处理时间1.5ms。


5. lucene相关原理

倒排索引:
倒排索引源于实际应用中需要根据属性的值来查找记录。这种索引表中的每一项都包括一个属性值和具有该属性值的各记录的地址。由于不是由记录来确定属性值,而是由属性值来确定记录的位置,因而称为倒排索引(inverted index)。带有倒排索引的文件我们称为倒排索引文件,简称倒排文件(inverted file)

倒排文件(倒排索引),索引对象是文档或者文档集合中的单词等,用来存储这些单词在一个文档或者一组文档中的存储位置,是对文档或者文档集合的一种最常用的索引机制。

搜索引擎的关键步骤就是建立倒排索引,倒排索引一般表示为一个关键词,然后是它的频度(出现的次数),位置(出现在哪一篇文章或网页中,及有关的日期,作者等信息),它相当于为互联网上几千亿页网页做了一个索引,好比一本书的目录、标签一般。读者想看哪一个主题相关的章节,直接根据目录即可找到相关的页面。不必再从书的第一页到最后一页,一页一页的查找。

倒排索引原理

压缩算法:
LZ4算法又称为Realtime Compression Algorithm,在操作系统(linux/freeBSD)、文件系统(OpenZFS)、大数据(Hadoop)、搜索引擎(Lucene/solr)、数据库(Hbase)……都可以看到它的身影,可以说是一个非常通用的算法。LZ4最突出的地方在于它的压缩/解压速度。

二元搜索:
二元搜索算法是在排好序的数组中找到特定的元素,类似key,value。首先, 比较数组中间的元素,如果相同,则返回此元素的指针,表示找到了. 如果不相同, 此函数就会继续搜索其中大小相符的一半,然后继续下去. 如果剩下的数组长度为0, 则表示找不到,那么函数就会结束。


6. 基本架构

lucene架构图

二、solr学习


1. solr是什么

Solr 是Apache下的一个顶级开源项目,采用Java开发,它是基于Lucene的全文搜索服务器。Solr提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展,并对索引、搜索性能进行了优化。
Solr可以独立运行,运行在Jetty、Tomcat等这些Servlet容器中,Solr 索引的实现方法很简单,用 POST 方法向 Solr 服务器发送一个描述 Field 及其内容的 XML 文档,Solr根据xml文档添加、删除、更新索引 。Solr 搜索只需要发送 HTTP GET 请求,然后对 Solr 返回Xml、json等格式的查询结果进行解析,组织页面布局。Solr不提供构建UI的功能,Solr提供了一个管理界面,通过管理界面可以查询Solr的配置和运行情况。


2. Solr7.1 版本与早期版本的对比

Solr7.1 与早期版本对比变化较大,如果基于旧版本的solr想迁移到新版本可以参考官方文档:Major Changes in Solr 7


3. solr7.1解压后目录介绍

1. bin 包含了几个重要的脚本,使用solr更Easy!
- solr 和 solr.cmd  这是Solr的控制脚本,也称为bin/solr(* nix)/ bin/solr.cmd(Windows)。这个脚本是启动和停止Solr的首选工具。您也可以在SolrCloud模式下运行时创建集合或内核,配置身份验证以及配置文件。
- post 提供了一个用于发布内容的命令行接口工具。支持导入JSON,XML和CSV,也可以导入HTML,PDF,Microsoft Office格式(如MS Word),纯文本等等。
- solr.in.sh 和 solr.in.cmd 用于配置solr的运行环境(jetty/java/solr)。
- install_solr_services.sh 将solr作为服务安装到系统中。

2. contrib Solr的contrib目录包含Solr专用功能的附加插件。

3. dist 包含了solr最主要的jar文件。

4. docs 包含了一个连接到在线的solr文档。

5. example 该example目录包括演示各种Solr功能的几种类型的示例。
- exampledocs 这是一系列简单的CSV,XML和JSON文件,可以bin/post在首次使用Solr时使用。
- example-DIH 此目录包含一些DataImport Handler(DIH)示例,可帮助您开始在数据库,电子邮件服务器甚至Atom订阅源中导入结构化内容。每个示例将索引不同的数据集; 有关这些示例的更多详细信息,请参阅README。
- files 该files目录为您可能在本地存储的文档(例如Word或PDF)提供基本的搜索UI。有关如何使用此示例的详细信息,请参阅README。
- films 该films目录包含一组关于电影的强大数据,包括三种格式:CSV,XML和JSON。有关如何使用此数据集的详细信息,请参阅README。

6. licenses 该licenses目录包括Solr使用的第三方库的所有许可证。

7. server solr的核心所在,该目录下的readme文件有详细介绍。

4. solr中常见的基本概念

4.1 solr.home

solr.home

Solr运行时,需要访问主目录(solr.home)。
当你第一次安装Solr时,你的主目录是server/solr。但是,一些示例可能会更改此位置(例如,如果您运行bin/solr start -e cloud,您的主目录将会example/cloud)。
Solr将在主目录下创建Core目录。可以使用 -s <dir> 命令修改值。如果手动设置目录,指定的目录应包含一个solr.xml文件,除非solr.xml存在于ZooKeeper中。默认值为server/solr。运行examples(-e)时忽略此参数,因为它solr.solr.home取决于运行的示例。
主目录包含重要的配置信息,并且是Solr将存储其索引的地方。在独立模式下运行Solr与在SolrCloud模式下运行时,主目录的布局会有所不同。
以下示例显示了Solr主目录中的关键部分:

solr.home目录

solr.home中的文件说明:

  • solr.xml 为您的Solr服务器实例指定配置选项。有关更多信息,solr.xml请参阅Solr Cores和solr.xml

  • 每个Solr核心文件夹

    • core.properties 为每个核心定义特定的属性,例如其名称,核心所属的集合,schema的位置以及其他参数。有关更多详细信息core.properties,请参阅定义core.properties一节。
    • solrconfig.xml 控制高级行为。例如,您可以为数据目录指定一个备用位置。有关更多信息solrconfig.xml,请参阅配置solrconfig.xml
    • managed-schema(旧版本叫做schema.xml) 描述您将要求Solr索引的文档。模式将文档定义为字段集合。您可以定义字段类型和字段本身。字段类型定义功能强大,包含有关Solr如何处理传入字段值和查询值的信息。有关Solr架构的更多信息,请参阅文档,字段和架构设计以及架构API
    • data/ 包含底层索引文件的目录。

请注意,SolrCloud模式Solr Core 的目录中没有conf目录(没有solrconfig.xml或Schema文件),这是因为conf目录中的配置文件存储在ZooKeeper中,它们可以在群集中传播。

如果您正在使用SolrCloud与嵌入式ZooKeeper的情况下,你还可以看到zoo.cfg和zoo.data它们是ZooKeeper管理配置和数据文件。但是,如果您正在运行自己的ZooKeeper集群,在启动ZooKeeper配置文件时,将会提供您自己的ZooKeeper配置文件,而Solr中的副本将不会被使用。有关SolrCloud的更多信息,请参阅SolrCloud部分。

4.2 schema(也称模式,其中包含Field、dynamicField、copyField、FieldType的定义)

solr中schema指的是managed-schema文件,其中预先定义了一些Field和FieldType,还定义了在对字段进行索引之前应该发生的修改。例如,如果要确保输入“abc”的用户和输入“ABC”的用户都可以找到包含术语“ABC”的文档,那么您需要规范化(在这种情况下,小写) )“ABC”,并将用户查询归一化以确保匹配。这些规则在您的模式中定义。

4.3 Schemaless Mode(无模式模式)

Schemaless Mode(无模式模式)是一组Solr功能,它们一起使用时,只需索引数据即可快速的构建schema,而无需手动编写schema。
这些Solr功能都是通过solrconfig.xml文件中控制的:

  • Managed schema(模式管理):在运行时通过Solr API进行架构修改,这需要使用支持这些更改的schemaFactory。有关更多详细信息,请参阅SolrConfig中的模式工厂定义部分。
  • Field value class guessing(字段猜测):对于未定义的Field,自动根据FieldValue猜测属于哪种Java类型(Boolean, Integer, Long, Float, Double, and Date )
  • Automatic schema field addition, based on field value class(es)(基于字段猜测自动添加Field到schema中):未定义的Field会根据FieldValue对应的Java类自动添加到schema - 请参阅Solr字段类型

建议关闭Schemaless Mode模式:

官网不推荐使用此功能,因为如果字段类型不正确,索引也就不能正常查询(例如存储汉字,我们如果不指定fileType最后就无法正常索引到汉字文档),官方原话:

It’s a bit brute force, and if it guesses wrong, you can’t change much about a field after data has been indexed without having to reindex. If we only have a few thousand documents that might not be bad, but if you have millions and millions of documents, or, worse, don’t have access to the original data anymore, this can be a real problem.

由于这些原因,Solr社区不建议在没有自己定义的模式的情况下进行生产。这样我们的意思是,无模式的功能开始是很好的,但您仍然应该始终确保您的模式符合您对数据索引的期望以及用户要查询的方式。

关闭schemaless模式有如下方式:

  1. 在solrconfig.xml文件中可以配置update.autoCreateFields:true为false即可关闭schemaless模式


    关闭schemaless模式
  2. 使用ConfigAPI关闭schemaless模式
    例如:

curl http://host:8983/solr/mycollection/config -d '{"set-user-property": {"update.autoCreateFields":"false"}}'

4.4 Field(字段)

1. fields属性说明
----------------------------------------------------------------
    name: 必须属性 - 字段名

    type: 必须属性 - <types>中定义的字段类型
    
    indexed: 如果字段需要被索引(用于搜索或排序),属性值设置为true
    
    stored: 如果字段内容需要被返回显示,值设置为true
    
    multiValued: 如果这个字段在每个文档中可能包含多个值,设置为true
    
    required:字段必须有值,否则会抛异常
    
    default: 在增加文档时,可以根据需要为字段设置一个默认值,防止为空
    
    termVectors: [false] 设置为true后,会保存所给字段的相关向量(vector),当使用MoreLikeThis时, 用于相似度判断的字段需要设置为stored来达到最佳性能.
    
    termPositions: 保存和向量相关的位置信息,会增加存储开销 
    
    termOffsets: 保存 offset 和向量相关的信息,会增加存储开销
    
    docValues: 如果这个字段应该有文档值(doc values),设置为true。文档值在门面搜索,分组,排序和函数查询中会非常有用。虽然不是必须的,而且会导致生成索引变大变慢,但这样设置会使索引加载更快,更加NRT友好,更高的内存使用效率。然而也有一些使用限制:目前仅支持StrField, UUIDField和所有 Trie*Fields, 并且依赖字段类型, 可能要求字段为单值(single-valued)的,必须的或者有默认值。
----------------------------------------------------------------

2. 性能优化:
----------------------------------------------------------------
  - 尽量将所有仅用于搜索,而不用于实际返回的字段设置stored="false"

  - 尽量将所有仅用于返回,而不用于搜索的字段设置indexed="false"

  - 去掉所有不需要的copyField 语句

  - 为了达到最佳的索引大小和搜索性能,对所有的文本字段设置indexed="false",使用copyField将他们拷贝到“整合字段”name="text"的字段中,使用整合字段进行搜索

  - 使用server模式来运行JVM,同时将log级别调高, 避免输出所有请求的日志。
----------------------------------------------------------------

详细字段设计可以参考:
http://lucene.apache.org/solr/guide/documents-fields-and-schema-design.html

4.5 dynamicField(动态字段)

动态字段(Dynamic fields)允许 solr 索引没有在 schema 中明确定义的字段。这个在忘记定义一些字段时很有用。动态字段可以让系统更灵活,通用性更强。

动态字段和常规字段类似,除了它名字中包含一个通配符外,在索引文档时,一个字段如果在常规字段中没有匹配时,将到动态字段中匹配。

假设schema中定义了一个叫*_i的动态动态字段,如果要索引一个叫 cost_i 的字段,但是 schema 中不存在 cost_i 的字段,这样 cost_i  将被索引到 *_i 字段中。

动态字段也是定义在 schema.xml 文件中,和其他字段一样,它也有个名词,字段类型,和属性。

4.6 copyField(复制字段)

现在你要查询包涵"Java"的博客, 那么你肯定要查内容,标题是否包含Java,但是solr不能像SQL那样,where tittle like '%Java%'  or  content like '%Java%'.   
这个时候copyField就派上用场了, 定义一个新字段,将title和content 复制到这个新字段,索引的时候,直接从这个新字段查询,这样就达到目地了。
这便是copyField的典型应用场景 。注意:如果dest由多个source构成,就需要将其指定为multiValued。

4.7 configSet(配置集目录,包含了示例config的文件夹)

当我们使用solr create 命令创建Core或者Collection时,需要使用-d 命令指定使用什么配置创建Core或者Collection,
如果不指定,则默认使用server/solr/configsets/_default作为Core或Collection配置。

4.8 默认查询字段—text字段

当我们查询字段时,如果没有指定字段查询,则使用默认字段text来查询:
例:q=book 等价于 q=text:book
为了达到最佳的索引大小和搜索性能,对所有的文本字段设置indexed="false",使用copyField将他们拷贝到“整合字段”name="text"的字段中,使用整合字段进行搜索。

<field name="title" type="text_general" indexed="false" stored="true" />    
      
<field name="content" type="text_general" indexed="false" stored="false" />    

<field name="text" type="text_general" indexed="true" stored="false" multiValued="true"/> 

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

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

修改默认搜素字段有两种方式:
solrconfig.xml的默认搜索配置权限高于schema.xml中的默认搜索配置!!!

配置1:solrconfig.xml文件中关于select的配置:

<requestHandler name="/select" class="solr.SearchHandler">
    <!-- default values for query parameters can be specified, these
         will be overridden by parameters in the request
      -->
    <lst name="defaults">
      <str name="echoParams">explicit</str>
      <int name="rows">10</int>
      <!-- Default search field
         <str name="df">text</str> 
        -->
      <!-- Change from JSON to XML format (the default prior to Solr 7.0)
         <str name="wt">xml</str> 
        -->
    </lst>
</requestHandler>


配置2:在schema.xml配置文件中找到<defaultSearchField>text</defaultSearchField>,一般默认情况下,这行配置是被注释的,取消注释,将text改成name。

4.9 facet—高级查询

Facet 是 solr 的高级搜索功能之一 , 可以给用户提供更友好的搜索体验 . 在搜索关键字的同时 , 能够按照 Facet 的字段进行分组并统计。
注意一点:facet.field指定的字段必须是可indexed的!!!否则无法查询!!!

常用的查询方式:

  • facet.field 查询指定字段的count
# 如果不想返回文档(docs)记录,可以指定rows=0
# 如果想设定count最小值筛选,可以指定facet.mincount=200

curl "http://localhost:8983/solr/films/select?q=*:*&rows=0&facet=true&facet.field=genre_str&facet.mincount=200"

查询结果:


facet.field
  • facet.range 对日期或数值划范围查询count
    使用facet.range的案例
# facet.range=initial_release_date 指定查询字段
# facet.range.start=NOW-20YEAR 指定查询区间开始值为20年前
# facet.range.end=NOW 指定查询区间结束值为现在
# facet.range.gap=%2B4YEAR 指定从开始区间到结束区间每4年统计一个count,%2B是URL转义字符表示+号

curl "http://localhost:8983/solr/films/select?q=*:*&rows=0&facet=true&facet.range=initial_release_date&facet.range.start=NOW-20YEAR&facet.range.end=NOW&facet.range.gap=%2B4YEAR"

查询结果:


facet.range
  • facet.pivot 多维分组(类似于group by a ,b的方式)查询count
# facet.pivot=genre_str,directed_by_str 指定分组条件,先以genre_str分组统计count
# 再分别对分组后的每组以directed_by_str分组统计count

curl "http://localhost:8983/solr/films/select?q=*:*&rows=0&facet=on&facet.pivot=genre_str,directed_by_str"

部分查询结果:


facet.pivot

更多用法请看solr facet查询及solrj 读取facet数据官方facet文档


5. solr常用命令

5.1 启动solr实例

启动solr

5.2 查看当前主机上所有solr实例的运行状态

查看solr实例状态

5.3 停止solr实例

停止solr实例

5.4 创建core或collection

创建core还是collection取决于Solr当前的运行模式(SolrCloud模式还是独立模式),如果启动solr时使用了-c ,则表示以SolrCloud模式启动solr,此时只能创建collection;相反,如果没有使用SolrCloud模式启动Solr,则此时只能创建core。


创建core或collection

5.5 删除core或collection

删除core或collection

6. post命令(用于导入数据的命令行工具,支持JSON,XML和CSV格式文件)

6.1 导入数据

# 例:
bin/post -c films example/films/films.json
导入命令

7. 常用查询命令

7.1 查询所有文档

格式:q=*:*

curl "http://localhost:8983/solr/techproducts/select?indent=on&q=*:*"

7.2 查询指定字段(Field:Value)

格式:q=fieldName:value

curl http://192.168.1.108:8983/solr/techproducts/select?q=cat:electronics

7.3 结合查询(Combining Search)

格式:q=+text:music -text:electronics

我们可以输入多个termphrase作为查询匹配条件,查询结果的排序也是由匹配度影响(==例如:q=apple banana pear ,此时如果文档1中包含全部3个term,文档2只包含2个,文档3只包含1个,则结果排序为文档1->文档2->文档3==),除此之外,我们还可以使用+、-号作为查询条件指定必须包含(+)与不能包含(-)某个term

curl http://127.0.0.1:8983/solr/techproducts/select?q=CAS latency

8. 添加自定义分词器(IK分词器)

8.1 准备

IK分词器下载

8.2 IK分词器介绍

  • ext.dic为扩展字典
  • stopword.dic为停止词字典
  • IKAnalyzer.cfg.xml为配置文件
  • solr-analyzer-ik-5.1.0.jar ik-analyzer-solr5-5.x.jar为分词jar包。

8.3 添加IK分词器

  1. 将IK分词器 JAR 包拷贝到solr7/server/solr_webapp/webapp/WEB-INF/lib/

  2. 将词典 配置文件拷贝到 solr7/server/solr_webapp/webapp/WEB-INF/

  3. 更改test_core\conf\managed-schema配置文件

<!-- 添加IK分词 -->
<fieldType name="text_ik" class="solr.TextField">
        <analyzer type="index">
            <tokenizer class="org.apache.lucene.analysis.ik.IKTokenizerFactory" useSmart="true"/>
        </analyzer>
        <analyzer type="query">
            <tokenizer class="org.apache.lucene.analysis.ik.IKTokenizerFactory" useSmart="true"/>
        </analyzer>
</fieldType>

9. DIH介绍

许多搜索应用程序将要索引的内容存储在结构化数据存储区(如关系数据库)中。数据导入处理程序(DIH)提供了一种从数据存储中导入内容并将其编入索引的机制。
除关系数据库之外,DIH还可以从基于HTTP的数据源(例如RSS和ATOM订阅源),电子邮件存储库以及使用XPath处理器生成字段的结构化XML中索引内容。

9.1 DIH概念和术语

数据导入处理程序的说明以特定的方式使用几个熟悉的术语,如实体和处理器,如下表所述。

Datasource 数据源
顾名思义,数据源定义了感兴趣的数据的位置。对于数据库来说,这是一个DSN。对于HTTP数据源,它是基本URL。

Entity 实体
从概念上讲,一个实体被处理以产生一组包含多个字段的文档,这些字段(在可选地以各种方式被转换之后)被发送到Solr用于索引。对于RDBMS数据源,实体是一个视图或表,它将由一个或多个SQL语句处理,以生成具有一个或多个列(字段)的一组行(文档)。

Processor 处理器
实体处理器完成从数据源中提取内容,转换它并将其添加到索引的工作。可以编写自定义实体处理器来扩展或替换提供的处理器。

Transformer 变压器
由实体提取的每一组字段可以可选地被转换。这个过程可以修改字段,创建新的字段,或者从单行生成多个行/文档。DIH中有几个内置的变压器,它们执行诸如修改日期和剥离HTML的功能。使用公共可用接口编写自定义变压器是可能的。

9.2 全量导入—配置DIH

库表

9.2.1 为DIH配置solrconfig.xml
数据导入处理程序必须注册solrconfig.xml。例如:

<requestHandler name="/dataimport" class="solr.DataImportHandler">
    <lst name="defaults">
      <str name="config">conf/db-data-config.xml</str>
    </lst>
</requestHandler>

9.2.2 配置DIH配置文件
在solrconfig.xml同级目录(conf)下建立db-data-config.xml配置文件。

<dataConfig>  
    <dataSource type="JdbcDataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://192.168.1.192:3306/gyoa_re?characterEncoding=UTF8" user="root" password="root" />   
    <document>  
        <entity name="item" query="select departmentId,departmentName,createTime,endTime from department">  
            <field column="departmentId" name="id"/>   
            <field column="departmentName" name="departmentName"/>   
            <field column="createTime" name="departCreateTime"/>   
            <field column="endTime" name="departEndTime"/>   
        </entity>  
    </document>  
</dataConfig>  

9.2.3 配置schema.xml
managed-schema文件中定义字段。由于上面db-data-config.xml中指定了departmentId对应的字段是id,而id是默认managed-schema中的唯一field,因此不需要再配置id字段。

  <!-- 添加的IK分词 -->
  <fieldType name="text_ik" class="solr.TextField">
            <analyzer type="index">
                <tokenizer class="org.apache.lucene.analysis.ik.IKTokenizerFactory" useSmart="true"/>
            </analyzer>
            <analyzer type="query">
                <tokenizer class="org.apache.lucene.analysis.ik.IKTokenizerFactory" useSmart="true"/>
            </analyzer>
  </fieldType>

  <!-- 配置部门field -->
  <field name="departmentName" type="text_ik" indexed="true" stored="true" />   
  <field name="departCreateTime" type="text_general" stored="true" />
  <field name="departEndTime" type="text_general" stored="true" />

9.2.4 加入JDBC驱动
将mysql的JDBC驱动放到部署到webapps下的solr的lib文件夹

9.2.5 加入导入相关的jar包
到solr的解压包的dist目录下找到solr-dataimporthandler-7.1.jar和solr-dataimporthandler-extras-7.1.jar这两个jar包,同样放到部署到webapps下的solr的lib文件夹

9.2.6 全量导入命令

full-import

9.2.7 查询索引

查询索引

9.3 增量导入—配置DIH

库表

9.3.1 为DIH配置solrconfig.xml
数据导入处理程序必须注册solrconfig.xml。例如:

<requestHandler name="/dataimport" class="solr.DataImportHandler">
    <lst name="defaults">
      <str name="config">conf/db-data-config.xml</str>
    </lst>
</requestHandler>

9.3.2 配置DIH配置文件
在solrconfig.xml同级目录(conf)下建立db-data-config.xml配置文件。

<dataConfig>  
    <dataSource type="JdbcDataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://192.168.1.192:3306/gyoa_re?characterEncoding=UTF8" user="root" password="root" />   
    <document name="doc">  
        <entity name="department" query="select departmentId,departmentName,createTime,endTime from department">  
            <field column="departmentId" name="id"/>   
            <field column="departmentName" name="departmentName"/>   
            <field column="createTime" name="departCreateTime"/>   
            <field column="endTime" name="departEndTime"/>   
        </entity>
        <entity name="user" pk="id" query="select * from solrUser"  deltaImportQuery="select * from solrUser where id ='${dih.delta.id}'" deltaQuery="select id from solrUser where updateTime> '${dataimporter.last_index_time}'">
            <field column="id" name="id"/>
            <field column="username" name="username"/>
            <field column="age" name="age"/>
            <field column="sex" name="sex"/>
            <field column="updateTime" name="updateTime"/>   
        </entity>
    </document>
</dataConfig>  

9.3.3 配置schema.xml
managed-schema文件中定义字段。由于上面db-data-config.xml中指定了departmentId对应的字段是id,而id是默认managed-schema中的唯一field,因此不需要再配置id字段。

  <!-- 添加的IK分词 -->
  <fieldType name="text_ik" class="solr.TextField">
            <analyzer type="index">
                <tokenizer class="org.apache.lucene.analysis.ik.IKTokenizerFactory" useSmart="true"/>
            </analyzer>
            <analyzer type="query">
                <tokenizer class="org.apache.lucene.analysis.ik.IKTokenizerFactory" useSmart="true"/>
            </analyzer>
  </fieldType>

  <!-- 配置部门field -->
  <field name="departmentName" type="text_ik" indexed="true" stored="true" />   
  <field name="departCreateTime" type="text_general" stored="true" />
  <field name="departEndTime" type="text_general" stored="true" />

  <!-- 配置solrUser的Field -->
  <field name="username" type="text_ik" indexed="true" stored="true" />
  <field name="age" type="text_ik" indexed="true" stored="true" />
  <field name="sex" type="text_ik" indexed="true" stored="true" />
  <field name="updateTime" type="pdate" stored="true" />

9.3.4 加入JDBC驱动
将mysql的JDBC驱动放到部署到webapps下的solr的lib文件夹

9.3.5 加入导入相关的jar包
到solr的解压包的dist目录下找到solr-dataimporthandler-7.1.jar和solr-dataimporthandler-extras-7.1.jar这两个jar包,同样放到部署到webapps下的solr的lib文件夹

9.3.6 增量导入数据操作

delta-import

9.3.7 查询新增的数据索引

查询新增的索引

9.3.8 更改数据库数据,重新执行增量导入数据操作,再次查询索引

数据更改后的库表
重新执行增量导入数据操作
再次查询索引

参考资料

  1. 什么是Lucene,Lucene能干什么

  2. 【手把手教你全文检索】Apache Lucene初探

推荐阅读更多精彩内容