Solr DIH: 基于MySQL表数据建立索引

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介:

选择使用Solr,对数据库中数据进行索引,可以单独写程序将数据库中的数据导出并建立索引,这个过程可能对于数据处理的控制更灵活一些,但是却可能带来很大的工作量。选择使用Solr的DIH组件,可以很方便的对数据库表中数据进行索引,下面基于MySQL数据库实现建立索引。

首先,需要设计你的schema,最主要的工作是,将数据库表中字段映射为Lucene索引(Solr直接使用Lucene的索引格式和数据)的Field,从而将数据表中的一条记录映射为Lucene中的Document,然后进行索引。另外,在schema.xml配置文件中,还需要指定各个字段在索引数据中的属性信息(如是否索引、是否存储、是否分词、排序规则等),以及Field所使用的分析器、过滤器等。在schema.xml文件进行配置,下面是配置实例:

01 <?xml version="1.0" ?>
02 <schema name="example core zero" version="1.1">
03 <types>
04 <fieldtype name="int" class="solr.IntField" omitNorms="true" />
05 <fieldtype name="string" class="solr.TextField" sortMissingLast="true"omitNorms="true">
06 <analyzer type="index">
07 <charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ISOLatin1Accent.txt" />
08 <tokenizer class="solr.KeywordTokenizerFactory" />
09 <filter class="solr.LowerCaseFilterFactory" />
10 </analyzer>
11 <analyzer type="query">
12 <tokenizer class="solr.KeywordTokenizerFactory" />
13 <filter class="solr.LowerCaseFilterFactory" />
14 </analyzer>
15 </fieldtype>
16 <fieldtype name="long" class="solr.LongField" omitNorms="true" />
17 <fieldtype name="date" class="solr.TrieDateField" sortMissingLast="true"omitNorms="true" />
18 <fieldtype name="text" class="solr.TextField" sortMissingLast="true"omitNorms="true">
19 <analyzer type="index">
20 <tokenizer class="solr.StandardTokenizerFactory" />
21 </analyzer>
22 <analyzer type="query">
23 <tokenizer class="solr.StandardTokenizerFactory" />
24 </analyzer>
25 </fieldtype>
26 </types>
27
28 <fields>
29 <field name="id" type="int" indexed="true" stored="true" multiValued="false"required="true" />
30 <field name="domain" type="string" indexed="true" stored="true"multiValued="false" required="false" />
31 <field name="alex_rank" type="int" indexed="true" stored="true"multiValued="false" required="false" />
32 <field name="server_port" type="string" indexed="true" stored="true"multiValued="false" required="false" />
33 <field name="cert_validity_notBefore" type="string" indexed="true"stored="true" multiValued="false" required="false" />
34 <field name="cert_validity_notAfter_yyyyMMdd" type="string" indexed="true"stored="true" multiValued="false" required="false" />
35 <field name="cert_issuer_brand" type="string" indexed="true" stored="true"multiValued="false" required="false" />
36 <field name="cert_validation" type="string" indexed="true" stored="true"multiValued="false" required="false" />
37 <field name="cert_isMultiDomain" type="string" indexed="true" stored="true"multiValued="false" required="false" />
38 <field name="cert_issuer_brand_isXRelated" type="string" indexed="true"stored="true" multiValued="false" required="false" />
39 <field name="cert_subject_C" type="string" indexed="true" stored="true"multiValued="false" required="false" />
40 <field name="cert_isWildcard" type="string" indexed="true" stored="true"multiValued="false" required="false" />
41 <field name="cert_notAfter" type="string" indexed="true" stored="true"multiValued="false" required="false" />
42 <field name="special_ssl" type="int" indexed="true" stored="true"multiValued="false" required="false" />
43 <field name="competitor_logo" type="string" indexed="true" stored="true"multiValued="false" required="false" />
44 <field name="segment" type="text" indexed="true" stored="false"multiValued="true" required="false" />
45 </fields>
46
47 <!-- field to use to determine and enforce document uniqueness. -->
48 <uniqueKey>id</uniqueKey>
49
50 <!-- field for the QueryParser to use when an explicit fieldname is absent -->
51 <defaultSearchField>domain</defaultSearchField>
52
53 <!-- SolrQueryParser configuration: defaultOperator="AND|OR" -->
54 <solrQueryParser defaultOperator="OR" />
55 </schema>

定义好上面的内容,就应该考虑从数据库表中如何查询出记录,然后通过处理进行索引。通常,对于已经存在的基于数据库的系统或应用,很可能需要对某些字段的值进行一些处理,然后再进行索引,使用Solr定义的一些组件,在一定程度上可以满足需要。比如,数据表中时间字段包含到毫秒,实际我们只需要到日期,所以进行索引之前要把时间字符串做截断处理,等等。
通过使用Solr的DIH(Data Import Handler)组件,可以很容易地进行配置,就能实现将数据库的数据进行索引,而且还提供了一些方便的操作,如全量索引、增量索引等功能。
下面,在solrconfig.xml中配置DIH对应的requestHandler,实际身上是暴露一个REST接口来实现数据库数据导出并索引,配置如下:

1 <requestHandler name="/dataimport"class="org.apache.solr.handler.dataimport.DataImportHandler">
2 <lst name="defaults">
3 <str name="config">data-config.xml</str>
4 </lst>
5 </requestHandler>

上面的请求接口为“/dataimport”,可以通过如下类似的URL执行数据导入处理:

1 http://172.0.8.212:8080/seaarch-server/core0/dataimport?command=full-import

上面DIH对应的requestHandler配置中,配置文件data-config.xml定义了数据库的基本配置,以及导出数据的映射规则,即导出数据库表中对应哪些字段的值,以及对特定字段的值做如何处理,下面是一个示例:

01 <dataConfig>
02 <dataSource name="jdbc" driver="com.mysql.jdbc.Driver"url="jdbc:mysql://172.0.8.249:5606/marketing_db_saved?zeroDateTimeBehavior=convertToNull" user="developer" password="sedept@shiyanjun.cn" />
03 <document name="mkt_data">
04 <entity name="marketing_data" pk="id" query="select * from marketing_data where id between ${dataimporter.request.offset} and ${dataimporter.request.offset}+1000000" deltaQuery="select * from marketing_data where updated_at &gt; '${dih.last_index_time}'" transformer="RegexTransformer">
05 <field column="id" name="id" />
06 <field column="domain" name="domain" />
07 <field column="alex_rank" name="alex_rank" />
08 <field column="server_port" name="server_port" />
09 <field column="cert_validity_notBefore" name="cert_validity_notBefore" />
10 <field column="cert_validity_notAfter" />
11 <field column="cert_validity_notAfter_yyyyMMdd" regex="(.*?)\s+.*"name="cert_validity_notAfter_yyyyMMdd" sourceColName="cert_validity_notAfter" />
12 <field column="cert_issuer_brand" name="cert_issuer_brand" />
13 <field column="cert_validation" name="cert_validation" />
14 <field column="cert_isMultiDomain" name="cert_isMultiDomain" />
15 <field column="cert_issuer_brand_isXRelated"name="cert_issuer_brand_isXRelated" />
16 <field column="cert_isWildcard" name="cert_isWildcard" />
17 <field column="cert_notAfter" name="cert_notAfter" />
18 <field column="special_ssl" name="special_ssl" />
19 <field column="competitor_logo" name="competitor_logo" />
20 <field column="segment" name="segment" />
21 </entity>
22 </document>
23 </dataConfig>

我们说明一下上面配置中的一些关键点:

全量索引

下面的SQL语句是与全量索引相关的:

1 SELECT * from marketing_data WHERE id between ${dataimporter.request.offset} AND${dataimporter.request.offset}+1000000

从表marketing_data中查询,表主键为id,查询条件为id between ${dataimporter.request.offset} and ${dataimporter.request.offset}+1000000,也就是id属于一个区间,而不是直接SELECT全表。Solr的DIH暴露了请求中传递的变量 ${dataimporter.request.offset},也就是在请求的requestHandler中可以附带附加属性条件,例如,下面请求URL中的offset=5000000参数:

1 http://172.0.8.212:8080/seaarch-server/core0/dataimport?command=full-import&offset=5000000

另外,还有一个参数是很重要的,它决定着是否清除已经存在的索引数据,默认为clean=true,如果不想删除以前的索引数据,一定要在请求的URL中指定该属性为false,请求URL如下:

1 http://172.0.8.212:8080/seaarch-server/core0/dataimport?command=full-import&offset=5000000&clean=false

另外,索引完成后一半需要执行commit操作,将内存中索引数据持久化到文件系统,防止改变丢失,所以需要在请求的URL中增加commit=true,例如:

1 http://172.0.8.212:8080/seaarch-server/core0/dataimport?command=full-import&offset=5000000&clean=false&commit=true

对于数据表中数据量很大的应用场景,通过这种方式,可以实现每次请求处理一批数据,避免对整个表造成过大的压力,影响正常线上业务操作数据库。

增量索引

上面requestHandler的配置中,属性配置内容:

1 deltaQuery="SELECT * from marketing_data WHERE updated_at &gt;'${dih.last_index_time}'

表示请求中指定的命令为增量索引方式,只需要通过指定请求的命令为delta-import即可,对应的请求URL为:

1 http://172.0.8.212:8080/search-server/core0/dataimport?command=delta-import

字段updated_at是数据表中时间戳的字段,where条件的含义是,如果上次索引时间点之后,表中记录的时间戳发生变化(即发生在上次索引之后),则对这些最近更新的记录进行索引(因为数据库表字段到LuceneField的映射中,使用的表主键id,如果是新增记录,则添加索引,就增加Document,如果只是更新表中记录,则对索引中已经存在的id相同的Document的数据进行更新)。

不过,上面两种方式还是需要手动干预处理批次,或者写个附加脚本进行成批索引。
还有一种更好的方式,可以直接在配置文件中进行配置,那就是属性文件dataimport.properties,它能够记录很多有用的状态,以及配置很多有用的选项。然而,这个功能在Solr 3.x版本中不能使用,如果使用的是Solr 4.x,可以使用。下面看一个示例配置:

01 #Tue Jul 21 12:10:50 CEST 2010
02 metadataObject.last_index_time=2010-09-20 11\:12\:47
03 last_index_time=2010-09-20 11\:12\:47
04
05
06 #################################################
07 # #
08 # dataimport scheduler properties #
09 # #
10 #################################################
11
12 # to sync or not to sync
13 # 1 - active; anything else - inactive
14 syncEnabled=1
15
16 # which cores to schedule
17 # in a multi-core environment you can decide which cores you want syncronized
18 # leave empty or comment it out if using single-core deployment
19 syncCores=coreHr,coreEn
20
21 # solr server name or IP address
22 # [defaults to localhost if empty]
23 server=localhost
24
25 # solr server port
26 # [defaults to 80 if empty]
27 port=8080
28
29 # application name/context
30 # [defaults to current ServletContextListener's context (app) name]
31 webapp=solrTest_WEB
32
33 # URL params [mandatory]
34 # remainder of URL
35 params=/search?qt=/dataimport&command=delta-import&clean=false&commit=true
36
37 # schedule interval
38 # number of minutes between two runs
39 # [defaults to 30 if empty]
40 interval=10

上面配置中,最后一个选项interval=10可以指定程序自动根据配置的时间间隔进行索引,而且上面的配置适合增量索引(可以从params=/search?qt=/dataimport&command=delta-import&clean=false&commit=true中的command=delta-import看出),因为它只需要根据对比上次索引时间和数据表中的更新时间戳字段来判断哪些数据需要进行索引或者更新索引数据。如果是实时性较强的应用,这个间隔自然可以设置短一些,保证基于搜索的应用的查询能够更接近实时,不过要根据自己应用的实际的需要去选择。

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
6天前
|
关系型数据库 MySQL 数据库
Mysql的索引
MYSQL索引主要有 : 单列索引 , 组合索引和空间索引 , 用的比较多的就是单列索引和组合索引 , 空间索引我这边没有用到过 单列索引 : 在MYSQL数据库表的某一列上面创建的索引叫单列索引 , 单列索引又分为 ● 普通索引:MySQL中基本索引类型,没有什么限制,允许在定义索引的列中插入重复值和空值,纯粹为了查询数据更快一点。 ● 唯一索引:索引列中的值必须是唯一的,但是允许为空值 ● 主键索引:是一种特殊的唯一索引,不允许有空值 ● 全文索引: 只有在MyISAM引擎、InnoDB(5.6以后)上才能使⽤用,而且只能在CHAR,VARCHAR,TEXT类型字段上使⽤用全⽂文索引。
|
2月前
|
存储 关系型数据库 MySQL
MySQL索引学习笔记
本文深入探讨了MySQL数据库中慢查询分析的关键概念和技术手段。
318 80
|
1月前
|
缓存 算法 关系型数据库
MySQL底层概述—8.JOIN排序索引优化
本文主要介绍了MySQL中几种关键的优化技术和概念,包括Join算法原理、IN和EXISTS函数的使用场景、索引排序与额外排序(Using filesort)的区别及优化方法、以及单表和多表查询的索引优化策略。
109 22
MySQL底层概述—8.JOIN排序索引优化
|
6天前
|
自然语言处理 关系型数据库 MySQL
MySQL索引有哪些类型?
● 普通索引:最基本的索引,没有任何限制。 ● 唯一索引:索引列的值必须唯一,但可以有空值。可以创建组合索引,则列值的组合必须唯一。 ● 主键索引:是特殊的唯一索引,不可以有空值,且表中只存在一个该值。 ● 组合索引:多列值组成一个索引,用于组合搜索,效率高于索引合并。 ● 全文索引:对文本的内容进行分词,进行搜索。
|
1月前
|
SQL 存储 关系型数据库
MySQL原理简介—9.MySQL索引原理
本文详细介绍了MySQL索引的设计与使用原则,涵盖磁盘数据页的存储结构、页分裂机制、主键索引设计及查询过程、聚簇索引和二级索引的原理、B+树索引的维护、联合索引的使用规则、SQL排序和分组时如何利用索引、回表查询对性能的影响以及索引覆盖的概念。此外还讨论了索引设计的案例,包括如何处理where筛选和order by排序之间的冲突、低基数字段的处理方式、范围查询字段的位置安排,以及通过辅助索引来优化特定查询场景。总结了设计索引的原则,如尽量包含where、order by、group by中的字段,选择离散度高的字段作为索引,限制索引数量,并针对频繁查询的低基数字段进行特殊处理等。
MySQL原理简介—9.MySQL索引原理
|
1月前
|
存储 关系型数据库 MySQL
MySQL底层概述—6.索引原理
本文详细回顾了:索引原理、二叉查找树、平衡二叉树(AVL树)、红黑树、B-Tree、B+Tree、Hash索引、聚簇索引与非聚簇索引。
101 11
MySQL底层概述—6.索引原理
|
2月前
|
存储 关系型数据库 MySQL
浅入浅出——MySQL索引
本文介绍了数据库索引的概念和各种索引结构,如哈希表、B+树、InnoDB引擎的索引运作原理等。还分享了覆盖索引、联合索引、最左前缀原则等优化技巧,以及如何避免索引误用,提高数据库性能。
|
2天前
|
关系型数据库 MySQL Java
【YashanDB知识库】原生mysql驱动配置连接崖山数据库
【YashanDB知识库】原生mysql驱动配置连接崖山数据库
【YashanDB知识库】原生mysql驱动配置连接崖山数据库
|
8天前
|
关系型数据库 MySQL 数据库连接
docker拉取MySQL后数据库连接失败解决方案
通过以上方法,可以解决Docker中拉取MySQL镜像后数据库连接失败的常见问题。关键步骤包括确保容器正确启动、配置正确的环境变量、合理设置网络和权限,以及检查主机防火墙设置等。通过逐步排查,可以快速定位并解决连接问题,确保MySQL服务的正常使用。
117 82
|
2月前
|
关系型数据库 MySQL 数据库连接
数据库连接工具连接mysql提示:“Host ‘172.23.0.1‘ is not allowed to connect to this MySQL server“
docker-compose部署mysql8服务后,连接时提示不允许连接问题解决