The Data Import Handler Framework
Solr includes a very popular contrib module for importing data known as the DataImportHandler (DIH in short). It's a data processing pipeline built specificallyfor Solr. Here's a summary of notable capabilities:
• Imports data from databases through JDBC (Java Database Connectivity)
° Supports importing only changed records, assuming a last-updated date
• Imports data from a URL (HTTP GET)
• Imports data from files (that is it crawls files)
• Imports e-mail from an IMAP server, including attachments
• Supports combining data from different sources
• Extracts text and metadata from rich document formats
• Applies XSLT transformations and XPath extraction on XML data
• Includes a diagnostic/development tool
The DIH is not considered a core part of Solr, even though it comes with the Solr download, and so you must add its Java JAR files to your Solr setup to use it. If this isn't done, you'll eventually see a ClassNotFoundException error. The DIH's JAR files are located in Solr's dist directory: apache-solr-dataimporthandler-3.4.0.jar and apache-solr-dataimporthandler-extras-3.4.0.jar. The easiest way to add JAR files to a Solr configuration is to copy them to the <solr_home>/lib directory; you may need to create it. Another method is to reference them from solrconfig.xml via <lib/> tags—see Solr's example configuration for examples of that. You will most likely need some additional JAR files as well. If you'll be communicating with a database, then you'll need to get a JDBC driver for it. If you will be extracting text from various document formats then you'll need to add the JARs in /contrib/extraction/lib. Finally, if you'll be indexing e-mail then you'll need to add the JARs in /contrib /dataimporthandler/lib.
The DIH needs to be registered with Solr in solrconfig.xml like so:
<requestHandler name="/dih_artists_jdbc" class="org.apache.solr.handler.dataimport.DataImportHandler"> <lst name="defaults"> <str name="config">mb-dih-artists-jdbc.xml</str> </lst> </requestHandler>
This reference mb-dih-artists-jdbc.xml is located in <solr-home>/conf, which specifies the details of a data importing process. We'll get to that file in a bit.
DIHQuickStart
http://wiki.apache.org/solr/DIHQuickStart
Index a DB table directly into Solr
Step 1 : Edit your solrconfig.xml to add the request handler
<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler"> <lst name="defaults"> <str name="config">data-config.xml</str> </lst> </requestHandler>
Step 2 : Create a data-config.xml file as follows and save it to the conf dir
<dataConfig> <dataSource type="JdbcDataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost/dbname" user="user-name" password="password"/> <document> <entity name="id" query="select id,name,desc from mytable"> </entity> </document> </dataConfig>
Step 3 : Ensure that your solr schema (schema.xml) has the fields 'id', 'name', 'desc'. Change the appropriate details in the data-config.xml
Step 4: Drop your JDBC driver jar file into the <solr-home>/lib directory .
Step 5 : Run the command
http://solr-host:port/solr/dataimport?command=full-import .
Keep in mind that every time a full-import is executed the index is cleaned up. If you do not wish that to happen add clean=false. For example:
http://solr-host:port/solr/dataimport?command=full-import&clean=false
Index the fields in different names
Step: 1 Change the data-config as follows :
<dataConfig> <dataSource type="JdbcDataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost/dbname" user="user-name" password="password"/> <document> <entity name="id" query="select id,name,desc from mytable"> <field column="id" name="solr_id"/> <field column="name" name="solr_name"/> <field column="desc" name="solr_desc"/> </entity> </document> </dataConfig>
Step 2 : This time the fields will be written to the solr fields 'solr_id', 'solr_name', solr_desc'. You must have these fields in the schema.xml.
Step 3 : Run the command http://solr-host:port/dataimpor?command=full-import
Index data from multiple tables into Solr
Step: 1 Change the data-config as follows :
<dataConfig> <dataSource type="JdbcDataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost/dbname" user="user-name" password="password"/> <document> <entity name="outer" query="select id,name,desc from mytable"> <field column="id" name="solr_id"/> <field column="name" name="solr_name"/> <field column="desc" name="solr_desc"/> <entity name="inner" query="select details from another_table where id ='${outer.id}'"> <field column="details" name="solr_details"/> </entity> </entity> </document> </dataConfig>
Step 2: The schema.xml should have the solr_details field
Step 3: Run the full-import command
配置数据源
将 dataSource标签直接添加到dataConfig下面,即成为dataConfig的子元素.
<dataSource type="JdbcDataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost/dbname" user="db_username" password="db_password"/>
- driver(必需的):jdbc驱动名称
- url(必需的):jdbc链接
- user:用户名
- password:密码
- 批量大小:jdbc链接中的批量大小
- 数据源也可以配置在solrconfig.xml中
- 属性type 指定了实现的类型。它是可选的。默认的实现是JdbcDataSource。
- 属性 name 是datasources的名字,当有多个datasources时,可以使用name属性加以区分
- 其他的属性都是随意的,根据你使用的DataSource实现而定。
- 当然 你也可以实现自己的DataSource。
多 数据源
<dataSource type="JdbcDataSource" name="ds-1" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://db1-host/dbname" user="db_username" password="db_password"/> <dataSource type="JdbcDataSource" name="ds-2" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://db2-host/dbname" user="db_username" password="db_password"/>
使用:
.. <entity name="one" dataSource="ds-1" ...> .. </entity> <entity name="two" dataSource="ds-2" ...> .. </entity> ..
配置data-config.xml
solr document是schema,它的域上的值可能来自于多个表.
data-config.xml的根元素是document。一个document元素代表了一种文档。 一个document元素中包含了一个或者多个root实体。一个root实体包含着一些子实体,这些子实体能够包含其他的实体。实体就是,关系数据库上 的表或者视图。每个实体都能够包含多个域,每个域对应着数据库返回结果中的一列。域的名字跟列的名字默认是一样的。如果一个列的名字跟solr field的名字不一样,那么属性name就应该要给出。其他的需要的属性在solrschema.xml文件中配置。
为了能够从数据库中取得想要的数据,我们的设计支持标准sql规范。这使得用户能够使用他任何想要的sql语句。root实体是一个中心表,使用它的列可 以把表连接在一起。
dataconfig的结构
dataconfig 的结构不是一成不变的,entity和field元素中的属性是随意的,这主要取决于processor和transformer。
以下是entity的默认属性
- name(必需的):name是唯一的,用以标识entity
- processor:只有当datasource不是RDBMS时才是必需的。默认值是 SqlEntityProcessor
- transformer:转换器将会被应用到这个entity上,详情请浏览transformer部分。
- pk:entity的主键,它是可选的,但使用“增量导入”的时候是必需。它跟schema.xml中定义的 uniqueKey没有必然的联系,但它们可以相同。
- rootEntity:默认情况下,document元素下就是根实体了,如果没有根实体的话,直接在实体下 面的实体将会被看做跟实体。对于根实体对应的数据库中返回的数据的每一行,solr都将生成一个document。
一下是SqlEntityProcessor的属性
-
query (required) :sql语句
-
deltaQuery : 只在“增量导入”中使用
-
parentDeltaQuery : 只在“增量导入”中使用
-
deletedPkQuery : 只在“增量导入”中使用
-
deltaImportQuery : (只在“增量导入”中使用) . 如果这个存在,那么它将会在“增量导入”中导入phase时代替query产生作用。这里有一个命名空间的用法${dataimporter.delta.}
Commands
打开导入数据界面http://192.168.0.248:9080/solr/admin/dataimport.jsp,看到几种按钮分别调用不同的导数据命令。
-
full-import : "完全导入"这个操作可以通过访问URL http://192.168.0.248:9080/solr/dataimport?command=full-import 完成。
-
这个操作,将会新起一个线程。response中的attribute属性将会显示busy。
-
这个操作执行的时间取决于数据集的大小。
-
当这个操作运行完了以后,它将在conf/dataimport.properties这个文件中记录下这个操作的开始时间
-
当“增量导入”被执行时,stored timestamp这个时间戳将会被用到
-
solr的查询在“完全导入”时,不是阻塞的
-
它还有下面一些参数:
-
clean : (default 'true'). 决定在建立索引之前,删除以前的索引。
-
commit : (default 'true'). 决定这个操作之后是否要commit
-
optimize : (default 'true'). 决定这个操作之后是否要优化。
-
debug : (default false). 工作在debug模式下。详情请看 the interactive development mode (see here )
-
-
-
delta-import : 当遇到一些增量的输入,或者发生一些变化时使用http://192.168.0.248:9080/solr/dataimport?command= delta-import .它同样支持 clean, commit, optimize and debug 这几个参数.
-
status : 想要知道命令执行的状态 , 访问 URL http://192.168.0.248:9080/solr/dataimport .它给出了关于文档创建、删除,查询、结果获取等等的详细状况。
-
reload-config : 如果data-config.xml已经改变,你不希望重启solr,而要重新加载配置时,运行一下的命令http://192.168.0.248:9080/solr/dataimport?command=reload-config
-
abort : 你可以通过访问 http://192.168.0.248:9080/solr/dataimport?command=abort 来终止一个在运行的操作
Full Import 例子
data-config.xml 如下:
<dataConfig> <dataSource driver="org.hsqldb.jdbcDriver" url="jdbc:hsqldb:/temp/example/ex" user="sa" /> <document name="products"> <entity name="item" query="select * from item"> <field column="ID" name="id" /> <field column="NAME" name="name" /> <field column="MANU" name="manu" /> <field column="WEIGHT" name="weight" /> <field column="PRICE" name="price" /> <field column="POPULARITY" name="popularity" /> <field column="INSTOCK" name="inStock" /> <field column="INCLUDES" name="includes" /> <entity name="feature" query="select description from feature where item_id='${item.ID}'"> <field name="features" column="description" /> </entity> <entity name="item_category" query="select CATEGORY_ID from item_category where item_id='${item.ID}'"> <entity name="category" query="select description from category where id = '${item_category.CATEGORY_ID}'"> <field column="description" name="cat" /> </entity> </entity> </entity> </document> </dataConfig>
这里, 根实体是一个名叫“item”的表,它的主键是id。我们使用语句 "select * from item"读取数据. 每一项都拥有多个特性。看下面feature实体的查询语句:
<entity name="feature" query="select description from feature where item_id='${item.id}'"> <field name="feature" column="description" /> </entity>
feature表中的外键item_id跟item中的主键连在一起从数据库中取得该row的数据。相同地,我们将item和category连表 (它们是多对多的关系)。注意,我们是怎样使用中间表和标准sql连表的:
<entity name="item_category" query="select category_id from item_category where item_id='${item.id}'"> <entity name="category" query="select description from category where id = '${item_category.category_id}'"> <field column="description" name="cat" /> </entity> </entity>
短一点的 data-config
在上面的例子中,这里有好几个从域到solr域之间的映射。如果域的名字和solr中域的名字是一样的话,完全避免使用在实体中配置域也是可以的。 当然,如果你需要使用转换器的话,你还是需要加上域实体的。
<dataConfig> <dataSource driver="org.hsqldb.jdbcDriver" url="jdbc:hsqldb:/temp/example/ex" user="sa" /> <document> <entity name="item" query="select * from item"> <entity name="feature" query="select description as features from feature where item_id='${item.ID}'"/> <entity name="item_category" query="select CATEGORY_ID from item_category where item_id='${item.ID}'"> <entity name="category" query="select description as cat from category where id = '${item_category.CATEGORY_ID}'"/> </entity> </entity> </document> </dataConfig>
访问 http://localhost:8983/solr/dataimport?command=full-import 执行一个“完全导入”
使用“增量导入”命令
你可以通过访问URL http://localhost:8983/solr/dataimport?command=delta-import 来使用增量导入。操 作将会新起一个线程,response中的属性statue也将显示busy now。操作执行的时间取决于你的数据集的大小。在任何时候,你都可以通过访问 http://localhost:8983/solr/dataimport 来查看状态。
当 增量导入被执行的时候,它读取存储在conf/dataimport.properties中的“start time”。它使用这个时间戳来执行增量查询,完成之后,会更新这个放在conf/dataimport.properties中的时间戳。
Delta-Import 例子
我们将使用跟“完全导入”中相同的数据库。注意,数据库已经被更新了,每个表都包含有一个额外timestamp类型的列 叫做last_modified。或许你需要重新下载数据库,因为它最近被更新了。我们使用这个时间戳的域来区别出那一行是上次索引以来有更新的。
看看下面的这个 data-config.xm:
<dataConfig> <dataSource driver="org.hsqldb.jdbcDriver" url="jdbc:hsqldb:/temp/example/ex" user="sa" /> <document name="products"> <entity name="item" pk="ID" query="select * from item" deltaQuery="select id from item where last_modified > '${dataimporter.last_index_time}'"> <entity name="feature" pk="ITEM_ID" query="select description as features from feature where item_id='${item.ID}'"> </entity> <entity name="item_category" pk="ITEM_ID, CATEGORY_ID" query="select CATEGORY_ID from item_category where ITEM_ID='${item.ID}'"> <entity name="category" pk="ID" query="select description as cat from category where id = '${item_category.CATEGORY_ID}'"> </entity> </entity> </entity> </document> </dataConfig>
注意到item实体的 属性deltaquery了吗,它包含了一个能够查出最近更新的sql语句。注意,变量{dataimporter.last_index_time } 是DataImporthandler传过来的变量,我们叫它时间戳,它指出“完全导入”或者“部分导入”的最后运行时间。你可以在data- config.xml文件中的sql的任何地方使用这个变量,它将在processing这个过程中被赋值。
上面例子中deltaQuery 只能够发现item中的更新,而不能发现其他表的。你可以像下面那样在一个sql语句中指定所有的表的更新:
deltaQuery="select id from item where id in (select item_id as id from feature where last_modified > '${dataimporter.last_index_time}') or id in (select item_id as id from item_category where item_id in (select id as item_id from category where last_modified > '${dataimporter.last_index_time}') or last_modified > '${dataimporter.last_index_time}') or last_modified > '${dataimporter.last_index_time}'"
写一个类似上面的庞大的deltaQuery 并不是一件很享受的工作,我们还是选择其他的方法来达到这个目的
<dataConfig> <dataSource driver="org.hsqldb.jdbcDriver" url="jdbc:hsqldb:/temp/example/ex" user="sa" /> <document> <entity name="item" pk="ID" query="select * from item" deltaQuery="select id from item where last_modified > '${dataimporter.last_index_time}'"> <entity name="feature" pk="ITEM_ID" query="select DESCRIPTION as features from FEATURE where ITEM_ID='${item.ID}'" deltaQuery="select ITEM_ID from FEATURE where last_modified > '${dataimporter.last_index_time}'" parentDeltaQuery="select ID from item where ID=${feature.ITEM_ID}"/> <entity name="item_category" pk="ITEM_ID, CATEGORY_ID" query="select CATEGORY_ID from item_category where ITEM_ID='${item.ID}'" deltaQuery="select ITEM_ID, CATEGORY_ID from item_category where last_modified > '${dataimporter.last_index_time}'" parentDeltaQuery="select ID from item where ID=${item_category.ITEM_ID}"> <entity name="category" pk="ID" query="select DESCRIPTION as cat from category where ID = '${item_category.CATEGORY_ID}'" deltaQuery="select ID from category where last_modified > '${dataimporter.last_index_time}'" parentDeltaQuery="select ITEM_ID, CATEGORY_ID from item_category where CATEGORY_ID=${category.ID}"/> </entity> </entity> </document> </dataConfig>
-
deltaQuery 取得从上次索引更新时间以来有更新的实体的主键。
-
parentDeltaQuery 从deltaQuery中取得当前表中更新的行,并把这些行提交给父表。因为,当子表中的一行发生改变时,我们需要更新它的父表的solr文档。
下面是一些值得注意的地方:
-
对于query语句返回的每一行,子实体的query都将被执行一次
-
对于deltaQuery返回的每一行,parentDeltaQuery都将被执行。
-
一旦根实体或者子实体中的行发生改变,我们将重新生成包含该行的solr文档。
补充:
query是获取全部数据的SQL
deltaImportQuery是获取增量数据时使用的SQL
deltaQuery是获取pk的SQL
parentDeltaQuery是获取父Entity的pk的SQL
Full Import工作原理:
执行本Entity的Query,获取所有数据;
针对每个行数据Row,获取pk,组装子Entity的Query;
执行子Entity的Query,获取子Entity的数据。
Delta Import工作原理:
查找子Entity,直到没有为止;
执行Entity的deltaQuery,获取变化数据的pk;
合并子Entity parentDeltaQuery得到的pk;
针对每一个pk Row,组装父Entity的parentDeltaQuery;
执行parentDeltaQuery,获取父Entity的pk;
执行deltaImportQuery,获取自身的数据;
如果没有deltaImportQuery,就组装Query
限制:
子Entity的query必须引用父Entity的pk
子Entity的parentDeltaQuery必须引用自己的pk
子Entity的parentDeltaQuery必须返回父Entity的pk
deltaImportQuery引用的必须是自己的pk
相关推荐
### Solr创建索引并查询的关键知识点 #### 一、Solr简介 Apache Solr是一款开源的全文搜索引擎平台,基于Lucene实现。它提供了一套完整的搜索解决方案,并且支持多种高级特性,如高亮显示、分面搜索、地理位置搜索...
### Solr创建索引的原理及解析 #### 一、Solr概述与索引机制 Apache Solr是一款基于Lucene的高性能全文检索服务器,广泛应用于网站的搜索功能中。Solr支持分布式部署,并且提供了丰富的API接口,方便与其他系统...
索引是设计表的一部分,创建的索引对sql的语句木有任何影响,对sql语句的执行效率有影响
### hbase+solr创建二级索引完整操作 #### 一、概述 本文档详细介绍了如何利用HBase和Solr创建二级索引的过程。通过整合HBase与Solr的优势,可以构建高性能的数据存储与检索系统。HBase作为分布式列族数据库,能够...
本示例讲解了如何利用Java多线程技术来有效地执行Solr创建索引的任务。 Solr是一个流行的开源全文搜索引擎,它提供了一个强大的、高度可配置的索引和查询服务。在处理大量数据时,单线程的索引创建可能成为性能瓶颈...
在macOS上安装Solr并索引MySQL_在macOS上安装Solr并索引MySQL
2. **增量创建索引**:Solr支持增量索引,意味着当新的数据加入或已有数据发生变化时,无需重新构建整个索引,而是只更新受影响的部分。这对于大型数据集来说,既节省时间又节省资源。 3. **创建索引**:索引是Solr...
全量索引是指将整个数据集插入 Solr 索引库中,一般用于第一次创建索引的情况。在这种情况下,我们需要将所有数据从数据源中提取出来,然后将其插入 Solr 索引库中。全量索引的优点是可以快速地创建索引,但其缺点是...
4. **创建索引**: 要对网站数据建立索引,首先需要将数据导入Solr。这通常通过Solr的DataImportHandler完成,它可以连接到数据库,抽取数据并转化为Solr可理解的格式。索引过程包括解析、分析和存储,其中分析阶段...
3. **创建映射**:在`data-config.xml`中,设置字段映射,将MySQL的字段与SOLR的字段对应起来,以便于构建索引。 4. **触发索引更新**:可以通过SOLR的API或Web界面来触发全量或增量数据导入,使SOLR根据MySQL中的...
3. **创建定时任务**:在Solr服务器的外部,如Linux服务器,你可以使用cron job或Windows的任务计划程序来定期执行更新索引的命令。命令通常是发送一个HTTP请求到Solr的Update Handler来触发数据导入。 4. **增量...
索引是通过将文档转换为一系列可搜索的字段来创建的,这些字段包括文本、数字、日期等。索引存储在磁盘上,并且可以被优化以提高查询性能。 2. **增量更新的概念** 增量更新是指只对发生变化的数据进行索引操作,...
1. **建立索引**:Solr通过分析和索引文档内容来创建索引,这个过程包括分词、词干提取、停用词过滤等文本预处理步骤。在本例中,虽然没有具体的源代码,但我们可以假设这些库文件如`wstx-asl-3.2.7.jar`(Woodstox ...
例如,可以创建一个名为"MySearch"的Solr集合,配置相应的字段类型和分析器,然后将数据库中的数据导入到索引中。用户可以通过查询接口发送查询请求,获取高亮且排序后的结果。 总结,Solr的查询和索引机制是其强大...
- **添加索引**:使用SolrNet,你可以创建一个SolrServer实例,然后调用Add方法向Solr添加文档。 - **查询索引**:使用SolrQuery类构造查询,然后通过SolrServer的Search方法执行查询,获取SolrResponse对象,从中...
主要讲解了 solr客户端如何调用带账号密码的solr服务器调用,实现添加索引和查询索引,以及分组查询
Solr 索引 测试报告 性能
包含solr介绍、全局索引介绍、ik分词器安装包、solr安装包、及各个部分的安装教程。
总之,"跟益达学Solr5之索引文件夹下所有文件"教程涵盖了从安装配置Solr5,创建核心,配置文件索引,到数据导入,查询优化以及监控维护等一系列步骤。通过学习这些内容,你可以掌握如何利用Solr5构建一个强大的文件...