【问题标题】:Run DELETE cleanup query after a Solr dataimport在 Solr 数据导入后运行 DELETE 清理查询
【发布时间】:2017-06-08 14:35:31
【问题描述】:

我正在处理来自 Oracle 数据库的 Solr dataimport。数据库系统有一组表,专门用于存储对其他表中更改的引用。 例如,我可能有一个名为PERSON 的表,当将记录添加到此表时,它们的ID 将添加到PERSON_CHANGED 表中。我想在定义我的deltaQuery 时使用这个PERSON_CHANGED 表,以便Solr 只索引后续索引中更改的记录。作为此过程的一部分,我需要在 Solr 完成导入(增量或完整)后从 PERSON_CHANGED 表中删除我已读取的记录,以便以后不再处理它们。

dataimport 之后运行这种“清理”SQL 查询的最佳方式是什么?

我尝试过像这样组合两个查询(为简洁起见):

<dataConfig>
    <dataSource ... >
    <document>
        <entity name="person"
                query="
                    SELECT ID, FIRST_NAME, LAST_NAME
                    FROM PERSON
                    WHERE '${dataimporter.request.clean}' != 'false'
                        OR PERSON_ID IN (
                            SELECT ID FROM CHANGED_PERSON
                        );

                    DELETE * (
                        SELECT * FROM CHANGED_PERSON
                    );
        " />
    </document>
</dataConfig>

但这会导致SQL command not properly ended 错误。 Solr 是否提供了一种方法来进行这种清理?

【问题讨论】:

  • 嗨,你的 SOLR 版本是多少?
  • @jeorfevre - 我正在使用 Solr 6.5.1。
  • 您的 Delete 语句未指定要用于删除的表,DELETE person where person_id in ( SELECT ID FROM CHANGED_PERSON );
  • 另外,我刚刚注意到您的 select 语句中没有定义 p.PERSON_ID 的别名引用。请务必附加“p”作为 PERSON 的表别名。
  • 谢谢@JairHernandez。我简化了这篇文章的查询,忘记删除别名。当我在我的 SQL 客户端应用程序中运行这两个查询(SELECT 和 DELETE)时,它们都可以正常工作。在 DELETE 语句中似乎不需要表名 - 我从这里遵循模式:stackoverflow.com/a/33262653/1063392

标签: sql oracle solr


【解决方案1】:

在 SOLR 中使用增量导入后,solr 不会处理两次您的记录,因为您每次运行时都会跟踪这些记录

参考文档:

当delta-import命令执行时,它会读取存储的开始时间 在 conf/dataimport.properties 中。

链接:https://wiki.apache.org/solr/DataImportHandler#Delta-Import_Example

作为您问题的一部分,我可以想象您每次运行 deltaimport 时都尝试执行完全导入(完全导入在 solr 索引中运行清理......等等)。这不是进行 deltaimport 的正确方法。

我建议你的是: 1)执行增量导入(而不是完全导入) 2) 每 X 天、X 个月一次,如果需要,执行干净导入 最好在另一个内核中执行此操作,以便您的服务继续运行,而您只需更换内核。

【讨论】:

  • 感谢您的回复!我认为只有将开始时间构建到查询中才有意义,就像他们在示例中所做的那样(当他们使用 '${dih.last_index_time}' 时)。我没有使用时间戳来确定我的增量是什么——而是使用我的CHANGED_PERSON 表。我计划运行一次完整导入,然后后续导入将使用此CHANGED_PERSON 表来确定尚未编制索引的内容。这就是为什么我需要能够在导入后从该表中删除。
  • 为什么不在您的PERSON表中使用时间戳,并删除TABLE CHANGED_PERSON,这样您就可以简单地使用somr delta mecanics。你需要 CHANGED_PERSON 表吗?
  • 我同意你的观点,像你建议的那样在 PERSON 表上使用时间戳会更简单,但是我们使用这个 CHANGED_PERSON 系统有很多原因 - 主要是由于遗留问题关注点以及与这些表交互的其他系统。
【解决方案2】:

我找到了完成这项清理任务的方法,但我对此并不满意。我可以定义一个单独的实体,其查询运行 DELETE:

<dataConfig>
    <dataSource ... >
    <document>
        <entity name="person"
                query="
                    SELECT ID, FIRST_NAME, LAST_NAME
                    FROM PERSON
                    WHERE '${dataimporter.request.clean}' != 'false'
                        OR PERSON_ID IN (
                            SELECT ID FROM CHANGED_PERSON
                        )" />

        <entity name="deleteChangedPersonRecords"
                query="DELETE FROM CHANGED_PERSON" />
    </document>
</dataConfig>

这似乎行得通,但它有点小技巧,它依赖于 Solr 以与文件中指定的相同顺序执行其实体查询的假设。如果有人有更好的解决方案,请随时添加您对此问题的答案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多