【问题标题】:Index a MySQL database with Apache Lucene, and keep them synchronized使用 Apache Lucene 索引 MySQL 数据库,并使它们保持同步
【发布时间】:2012-05-31 09:48:43
【问题描述】:
  1. 在 MySQL 中添加新项目时,它也必须被 Lucene 索引。
  2. 从 MySQL 中删除现有项时,它也必须从 Lucene 的索引中删除。

这个想法是编写一个脚本,该脚本将通过调度程序每 x 分钟调用一次(例如 CRON 任务)。这是一种保持 MySQL 和 Lucene 同步的方法。到目前为止我所管理的:

  1. 对于 MySQL 中的每个新添加项,Lucene 也会对其进行索引。
  2. 对于 MySQL 中已添加的每个项目,Lucene 不会对其重新编制索引(没有重复的项目)。

这就是我请求你帮助管理的一点:

  1. 对于之前添加的每个已从 MySQL 中删除的项目,Lucene 也应取消索引。

这是我使用的代码,它试图索引一个 MySQL 表 tag (id [PK] | name)

public static void main(String[] args) throws Exception {

    Class.forName("com.mysql.jdbc.Driver").newInstance();
    Connection connection = DriverManager.getConnection("jdbc:mysql://localhost/mydb", "root", "");
    StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_36);
    IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_36, analyzer);
    IndexWriter writer = new IndexWriter(FSDirectory.open(INDEX_DIR), config);

    String query = "SELECT id, name FROM tag";
    Statement statement = connection.createStatement();
    ResultSet result = statement.executeQuery(query);

    while (result.next()) {
        Document document = new Document();
        document.add(new Field("id", result.getString("id"), Field.Store.YES, Field.Index.NOT_ANALYZED));
        document.add(new Field("name", result.getString("name"), Field.Store.NO, Field.Index.ANALYZED));
        writer.updateDocument(new Term("id", result.getString("id")), document);
    }

    writer.close();

}

PS:此代码仅用于测试目的,无需告诉我它有多糟糕:)

编辑:

一种解决方案是删除任何预先添加的文档,并重新索引所有数据库:

writer.deleteAll();
while (result.next()) {
    Document document = new Document();
    document.add(new Field("id", result.getString("id"), Field.Store.YES, Field.Index.NOT_ANALYZED));
    document.add(new Field("name", result.getString("name"), Field.Store.NO, Field.Index.ANALYZED));
    writer.addDocument(document);
}

我不确定这是最优化的解决方案,是吗?

【问题讨论】:

  • 你最后做了什么?

标签: java mysql lucene synchronization indexing


【解决方案1】:

只要您让索引/重新索引与您的应用程序分开运行,您就会遇到同步问题。根据您的工作领域,这可能不是问题,但对于许多并发用户应用程序来说却是。

当我们的作业系统每隔几分钟运行一次异步索引时,我们也遇到了同样的问题。用户会使用搜索引擎找到产品,然后即使管理员从有效产品堆栈中删除了产品,仍然会在前端找到它,直到下一个重新索引作业运行。这会导致向一级支持报告非常混乱且很少可重现的错误。

我们看到了两种可能性:要么将业务逻辑紧密连接到搜索索引的更新,要么实现更紧密的异步更新任务。我们做了后者。

在后台,有一个类在 tomcat 应用程序内的专用线程中运行,该线程接受更新并并行运行它们。后台更新到前端的等待时间降至0.5-2秒,大大减少了一级支持的问题。而且,它尽可能地松散耦合,我们甚至可以实现不同的索引引擎。

【讨论】:

    【解决方案2】:

    看看 Solr DataImportScheduler 方法。
    基本上,当 Web 应用程序启动时,它会生成一个单独的 Timer 线程,该线程会定期针对 Solr 触发 HTTP Post,然后使用您设置的 DataImportHandler 从 RDB(和其他数据源)中提取数据。

    因此,由于您没有使用 Solr,而仅使用 Lucene,因此您应该查看 DataImportHandler source 以获取想法。

    【讨论】:

      猜你喜欢
      • 2011-07-14
      • 1970-01-01
      • 1970-01-01
      • 2020-06-09
      • 2010-09-07
      • 2020-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多