使用数据处理程序导入后,Solr 不返回所有文档
Solr not returning all documents after importing with the Data Handler
我安装了 Solr 8.7.0,我正在通过 MySQLi 连接使用数据处理程序导入程序插件。
我声明了四个实体:
<dataConfig>
<dataSource type="JdbcDataSource"
driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/hmsscot_bassculture"
user="myuser"
password="mypw"/>
<document>
<entity name="author" query="select id,type,firstname,surname,biographical_info,extrainfo from bassculture_author">
<field column="id" name="id"/>
<field column="type" name="type"/>
<field column="firstname" name="firstname"/>
<field column="surname" name="surname"/>
<field column="biographical_info" name="biographical_info"/>
<field column="extrainfo" name="extrainfo"/>
</entity>
<entity name="source" query="select id,type,short_title,full_title,publisher,author_id,orientation,variants from bassculture_source">
<field column="id" name="id"/>
<field column="type" name="type"/>
<field column="short_title" name="short_title"/>
<field column="full_title" name="full_title"/>
<field column="publisher" name="publisher"/>
<field column="author_id" name="author_id"/>
<entity name="author" query="SELECT s.*, CONCAT(ba.firstname, ' ', ba.surname) AS author FROM bassculture_source s, bassculture_author ba WHERE s.id=${source.id} AND s.author_id = ba.id;">
<field column="author" name="author"/>
</entity>
<field column="description" name="description"/>
<field column="orientation" name="orientation"/>
<field column="variants" name="variants"/>
</entity>
<entity name="copy" query="select id,type,folder,source_id,item_notes,seller,library,shelfmark,pagination,dimensions from bassculture_item">
<field column="id" name="id"/>
<field column="type" name="type"/>
<field column="folder" name="folder"/>
<field column="source_id" name="source_id"/>
<entity name="source_title" query="select id,short_title from bassculture_source where id=${copy.source_id}">
<field column="short_title" name="source_title"/>
</entity>
<entity name="source_author" query="SELECT bt.*, CONCAT(ba.firstname, ' ', ba.surname) AS source_author FROM bassculture_tune bt, bassculture_item c, bassculture_source s, bassculture_author ba WHERE c.id=${copy.id} AND c.source_id = s.id AND s.author_id = ba.id;">
<field column="source_author" name="source_author"/>
</entity>
<field column="item_notes" name="item_notes"/>
<field column="seller" name="seller"/>
<field column="library" name="library"/>
<field column="shelfmark" name="shelfmark"/>
<field column="paginations" name="pagination"/>
<field column="dimensions" name="dimension"/>
</entity>
<entity name="tune" query="select id,type,name,start_page,alternate_spellings,item_id from bassculture_tune">
<field column="id" name="id"/>
<field column="type" name="type"/>
<field column="name" name="name"/>
<entity name="source_title" query="select s.* FROM bassculture_source s, bassculture_item c, bassculture_tune bt where bt.id=${tune.id} AND c.source_id = s.id AND bt.item_id = c.id">
<field column="short_title" name="source_title"/>
</entity>
<entity name="tune_author" query="SELECT bt.*, CONCAT(ba.firstname, ' ', ba.surname, ' ', ba.extrainfo) AS tune_author FROM bassculture_tune bt, bassculture_item c, bassculture_source s, bassculture_author ba WHERE bt.id=${tune.id} AND bt.item_id = c.id AND c.source_id = s.id AND s.author_id = ba.id;">
<field column="tune_author" name="tune_author" />
</entity>
<field column="start_page" name="start_page"/>
<field column="alternate_spellings" name="alternate_spellings"/>
<field column="item_id" name="item_id"/>
</entity>
</document>
</dataConfig>
现在,我正在经历一些对我来说没有意义的事情。如果我 运行 数据导入器将 'entity' 下拉列表留空(即导入所有实体):
我得到:
索引完成。 Added/Updated:2357 个文件。已删除 0 个文档。 (持续时间:13 秒)
这是正确的文件数量(作者+来源+副本+曲调)。然而,当我查询数据库时,我只得到 1938 个文档:
"responseHeader":{
"status":0,
"QTime":103,
"params":{
"q":"*:*",
"_":"1609335106436"}},
"response":{"numFound":1938,"start":0,"numFoundExact":true,"docs":[
{
[...]
这只是曲调(上面配置文件中的最后一个实体)。我也在仪表板中看到了这个:
如果另一方面我 select 实体一个一个(例如作者等...):
插件正确导入作者、调整和复制实体(每次 . 查询反映导入的文档)。一旦我到达第四个实体(调整),索引显然 'forgets' 关于前三个实体 - 尽管在 运行 之后,插件报告 'documents deleted: 0' - 和 . 查询返回到仅找到 1938 个文档(即仅找到曲调)。
日志中没有错误消息。我错过了什么?
部分解决方案
为了区分四种不同的数据,我设法给id添加了一个前缀,这样唯一的id就不会被重写,例如:
SELECT name,start_page,alternate_spellings,item_id, CONCAT('tune_', id) AS id, 'tune' as type FROM bassculture_tune;
尽管如此,我需要当前曲调的数据库 ID(不带前缀),在这种情况下,以便稍后进行比较,例如:
<entity name="tune_author" query="SELECT bt.*, CONCAT(ba.firstname, ' ', ba.surname, ' ', ba.extrainfo) AS tune_author FROM bassculture_tune bt, bassculture_item c, bassculture_source s, bassculture_author ba WHERE bt.id=${tune.id} AND bt.item_id = c.id AND c.source_id = s.id AND s.author_id = ba.id;">
<field column="tune_author" name="tune_author" />
</entity>
由于 ${tune.id} 现在有一个前缀,所以整个查询不再执行我需要的操作。有没有办法在本地去除前缀?
编辑 2
查询
<entity name="tune_author" query="select s.* FROM bassculture_source s, bassculture_item c, bassculture_tune bt WHERE bt.id=REPLACE(${tune.id}, 'tune_', '') AND c.source_id = s.id AND bt.item_id = c.id;">
在 Solr 上导入数据时引发错误(无法执行查询)。
这是 Solr 日志中的错误:
Caused by: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT REPLACE(tune_1, 'tune_', ''), AND c.source_id = s.id AND bt.item_id = c.i' at line 1
PS
类似
select item_id FROM bassculture_tune bt WHERE bt.id= (SELECT REPLACE('tune_1', 'tune_', ''));
在 MySQL 控制台上工作正常。
引入变量
我现在正在用变量试试运气:
<entity name="this_tune_id" query="SET @this_tune_id = REPLACE('${tune.id}','tune_','');">
</entity>
<entity name="source_title" query="select s.* FROM bassculture_source s, bassculture_item c, bassculture_tune bt WHERE c.source_id = s.id AND bt.item_id = c.id AND bt.id = ${this_tune_id};">
<field column="short_title" name="source_title"/>
</entity>
这给了我一个
org.apache.solr.handler.dataimport.DataImportHandlerException: java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 1
错误。
最终解决方案
我将数据库 ID 存储为 this_tune_id,并将 Solr id(带有前缀)存储为 id,这样我就可以使用 this_tune_id 进行查询,同时仍将带前缀的 id 存储在索尔:
<entity name="tune" query="SELECT name,start_page,alternate_spellings,item_id, id AS this_tune_id, CONCAT('tune_', id) AS id, 'tune' as type FROM bassculture_tune;">
<field column="name" name="name"/>
<entity name="source_title" query="select s.* FROM bassculture_source s, bassculture_item c, bassculture_tune bt WHERE c.source_id = s.id AND bt.item_id = c.id AND bt.id = ${tune.this_tune_id};">
包含您导入数据的屏幕截图揭示了原因:maxDocs
显示已导入 2357 个文档;但有 419 个已被标记为已删除。您的唯一关键字段(通常 id
)在您导入的文档之间有重叠,导致较新的文档覆盖较旧的文档。
419 个文档已被后来导入的文档覆盖,因为 id 重叠。
您可以通过在您的 ID 前添加实体类型来解决此问题(ID 无需为数字)- 最简单的方法是在您的 SQL:
中添加前缀
SELECT CONCAT('tune_', id) AS id, FROM ..
SELECT CONCAT('author_', id) AS id, .. FROM ..
... repeating for each source ..
这样一来,作者的 ID 将是 author_1
,并且不会覆盖 tune_1
,否则两者都会将 1
作为其 ID。
我安装了 Solr 8.7.0,我正在通过 MySQLi 连接使用数据处理程序导入程序插件。
我声明了四个实体:
<dataConfig>
<dataSource type="JdbcDataSource"
driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/hmsscot_bassculture"
user="myuser"
password="mypw"/>
<document>
<entity name="author" query="select id,type,firstname,surname,biographical_info,extrainfo from bassculture_author">
<field column="id" name="id"/>
<field column="type" name="type"/>
<field column="firstname" name="firstname"/>
<field column="surname" name="surname"/>
<field column="biographical_info" name="biographical_info"/>
<field column="extrainfo" name="extrainfo"/>
</entity>
<entity name="source" query="select id,type,short_title,full_title,publisher,author_id,orientation,variants from bassculture_source">
<field column="id" name="id"/>
<field column="type" name="type"/>
<field column="short_title" name="short_title"/>
<field column="full_title" name="full_title"/>
<field column="publisher" name="publisher"/>
<field column="author_id" name="author_id"/>
<entity name="author" query="SELECT s.*, CONCAT(ba.firstname, ' ', ba.surname) AS author FROM bassculture_source s, bassculture_author ba WHERE s.id=${source.id} AND s.author_id = ba.id;">
<field column="author" name="author"/>
</entity>
<field column="description" name="description"/>
<field column="orientation" name="orientation"/>
<field column="variants" name="variants"/>
</entity>
<entity name="copy" query="select id,type,folder,source_id,item_notes,seller,library,shelfmark,pagination,dimensions from bassculture_item">
<field column="id" name="id"/>
<field column="type" name="type"/>
<field column="folder" name="folder"/>
<field column="source_id" name="source_id"/>
<entity name="source_title" query="select id,short_title from bassculture_source where id=${copy.source_id}">
<field column="short_title" name="source_title"/>
</entity>
<entity name="source_author" query="SELECT bt.*, CONCAT(ba.firstname, ' ', ba.surname) AS source_author FROM bassculture_tune bt, bassculture_item c, bassculture_source s, bassculture_author ba WHERE c.id=${copy.id} AND c.source_id = s.id AND s.author_id = ba.id;">
<field column="source_author" name="source_author"/>
</entity>
<field column="item_notes" name="item_notes"/>
<field column="seller" name="seller"/>
<field column="library" name="library"/>
<field column="shelfmark" name="shelfmark"/>
<field column="paginations" name="pagination"/>
<field column="dimensions" name="dimension"/>
</entity>
<entity name="tune" query="select id,type,name,start_page,alternate_spellings,item_id from bassculture_tune">
<field column="id" name="id"/>
<field column="type" name="type"/>
<field column="name" name="name"/>
<entity name="source_title" query="select s.* FROM bassculture_source s, bassculture_item c, bassculture_tune bt where bt.id=${tune.id} AND c.source_id = s.id AND bt.item_id = c.id">
<field column="short_title" name="source_title"/>
</entity>
<entity name="tune_author" query="SELECT bt.*, CONCAT(ba.firstname, ' ', ba.surname, ' ', ba.extrainfo) AS tune_author FROM bassculture_tune bt, bassculture_item c, bassculture_source s, bassculture_author ba WHERE bt.id=${tune.id} AND bt.item_id = c.id AND c.source_id = s.id AND s.author_id = ba.id;">
<field column="tune_author" name="tune_author" />
</entity>
<field column="start_page" name="start_page"/>
<field column="alternate_spellings" name="alternate_spellings"/>
<field column="item_id" name="item_id"/>
</entity>
</document>
</dataConfig>
现在,我正在经历一些对我来说没有意义的事情。如果我 运行 数据导入器将 'entity' 下拉列表留空(即导入所有实体):
我得到:
索引完成。 Added/Updated:2357 个文件。已删除 0 个文档。 (持续时间:13 秒)
这是正确的文件数量(作者+来源+副本+曲调)。然而,当我查询数据库时,我只得到 1938 个文档:
"responseHeader":{
"status":0,
"QTime":103,
"params":{
"q":"*:*",
"_":"1609335106436"}},
"response":{"numFound":1938,"start":0,"numFoundExact":true,"docs":[
{
[...]
这只是曲调(上面配置文件中的最后一个实体)。我也在仪表板中看到了这个:
如果另一方面我 select 实体一个一个(例如作者等...):
插件正确导入作者、调整和复制实体(每次 . 查询反映导入的文档)。一旦我到达第四个实体(调整),索引显然 'forgets' 关于前三个实体 - 尽管在 运行 之后,插件报告 'documents deleted: 0' - 和 . 查询返回到仅找到 1938 个文档(即仅找到曲调)。
日志中没有错误消息。我错过了什么?
部分解决方案
为了区分四种不同的数据,我设法给id添加了一个前缀,这样唯一的id就不会被重写,例如:
SELECT name,start_page,alternate_spellings,item_id, CONCAT('tune_', id) AS id, 'tune' as type FROM bassculture_tune;
尽管如此,我需要当前曲调的数据库 ID(不带前缀),在这种情况下,以便稍后进行比较,例如:
<entity name="tune_author" query="SELECT bt.*, CONCAT(ba.firstname, ' ', ba.surname, ' ', ba.extrainfo) AS tune_author FROM bassculture_tune bt, bassculture_item c, bassculture_source s, bassculture_author ba WHERE bt.id=${tune.id} AND bt.item_id = c.id AND c.source_id = s.id AND s.author_id = ba.id;">
<field column="tune_author" name="tune_author" />
</entity>
由于 ${tune.id} 现在有一个前缀,所以整个查询不再执行我需要的操作。有没有办法在本地去除前缀?
编辑 2
查询
<entity name="tune_author" query="select s.* FROM bassculture_source s, bassculture_item c, bassculture_tune bt WHERE bt.id=REPLACE(${tune.id}, 'tune_', '') AND c.source_id = s.id AND bt.item_id = c.id;">
在 Solr 上导入数据时引发错误(无法执行查询)。
这是 Solr 日志中的错误:
Caused by: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT REPLACE(tune_1, 'tune_', ''), AND c.source_id = s.id AND bt.item_id = c.i' at line 1
PS
类似
select item_id FROM bassculture_tune bt WHERE bt.id= (SELECT REPLACE('tune_1', 'tune_', ''));
在 MySQL 控制台上工作正常。
引入变量
我现在正在用变量试试运气:
<entity name="this_tune_id" query="SET @this_tune_id = REPLACE('${tune.id}','tune_','');">
</entity>
<entity name="source_title" query="select s.* FROM bassculture_source s, bassculture_item c, bassculture_tune bt WHERE c.source_id = s.id AND bt.item_id = c.id AND bt.id = ${this_tune_id};">
<field column="short_title" name="source_title"/>
</entity>
这给了我一个
org.apache.solr.handler.dataimport.DataImportHandlerException: java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 1
错误。
最终解决方案
我将数据库 ID 存储为 this_tune_id,并将 Solr id(带有前缀)存储为 id,这样我就可以使用 this_tune_id 进行查询,同时仍将带前缀的 id 存储在索尔:
<entity name="tune" query="SELECT name,start_page,alternate_spellings,item_id, id AS this_tune_id, CONCAT('tune_', id) AS id, 'tune' as type FROM bassculture_tune;">
<field column="name" name="name"/>
<entity name="source_title" query="select s.* FROM bassculture_source s, bassculture_item c, bassculture_tune bt WHERE c.source_id = s.id AND bt.item_id = c.id AND bt.id = ${tune.this_tune_id};">
包含您导入数据的屏幕截图揭示了原因:maxDocs
显示已导入 2357 个文档;但有 419 个已被标记为已删除。您的唯一关键字段(通常 id
)在您导入的文档之间有重叠,导致较新的文档覆盖较旧的文档。
419 个文档已被后来导入的文档覆盖,因为 id 重叠。
您可以通过在您的 ID 前添加实体类型来解决此问题(ID 无需为数字)- 最简单的方法是在您的 SQL:
中添加前缀SELECT CONCAT('tune_', id) AS id, FROM ..
SELECT CONCAT('author_', id) AS id, .. FROM ..
... repeating for each source ..
这样一来,作者的 ID 将是 author_1
,并且不会覆盖 tune_1
,否则两者都会将 1
作为其 ID。