【问题标题】:Solr not returning all documents after importing with the Data Handler使用数据处理程序导入后,Solr 未返回所有文档
【发布时间】:2020-12-30 13:37:55
【问题描述】:

我安装了 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>

现在,我正在经历一些对我来说没有意义的事情。如果我运行数据导入器,将“实体”下拉列表留空(即导入所有实体):

我明白了:

索引已完成。添加/更新:2357 个文档。删除了 0 个文档。 (时长:13 秒)

这是正确的文档数量(作者+来源+副本+曲调)。然而,当我查询数据库时,我只得到 1938 个文档:

  "responseHeader":{
    "status":0,
    "QTime":103,
    "params":{
      "q":"*:*",
      "_":"1609335106436"}},
  "response":{"numFound":1938,"start":0,"numFoundExact":true,"docs":[
      {
    [...]

这只是曲调(上面配置文件中的最后一个实体)。我也在仪表板中看到了这一点:

另一方面,如果我一个接一个地选择实体(例如作者等...):

插件正确导入作者、调整和复制实体(每次 . 查询都反映了导入的文档)。一旦我到达第四个实体(调整),索引显然会“忘记”前三个实体 - 尽管在运行它之后,插件报告'文档已删除: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

附言

类似

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 存储在 Solr 中:

<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};">

【问题讨论】:

    标签: mysql solr dataimporthandler


    【解决方案1】:

    包含您导入数据的屏幕截图揭示了原因: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。

    【讨论】:

    • 谢谢,这确实是个问题。这给了我一个“无法执行查询”:&lt;entity name="author" query="select type,firstname,surname,biographical_info,extrainfo from bassculture_author"&gt; &lt;entity name="id" query="SELECT CONCAT('author_', id) AS id FROM bassculture_author WHERE bassculture_author.id=${author.id};"&gt; &lt;/entity&gt;。如果我直接使用SELECT CONCAT('author_', id) AS id FROM bassculture_author WHERE bassculture_author.id=1; 查询数据库,我会得到一个“author_1”。
    • 不需要内部查询,只需在您的第一个查询中添加 CONCAT(..) AS id。
    猜你喜欢
    • 2015-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多