指数MySQL数据库和Apache Lucene的,并保持同步(Index a MySQL data

2019-07-29 16:15发布

  1. 当一个新的项目在MySQL中添加,它必须也Lucene的索引。
  2. 当现有的项目从MySQL删除,它也必须从Lucene的索引中删除。

我们的想法是写一个脚本,将每x分钟内通过调度(例如,一个cron任务)被调用。 这是保持MySQL和Lucene的同步的方式。 我管理,直到尚未:

  1. 对于MySQL中的每个新添加的项目,Lucene索引它。
  2. 对于MySQL中的每个已添加的项目,Lucene的不重新索引它(没有重复项)。

这是我在问你一些帮助管理点:

  1. 对于每个先前添加的项目已经然后从MySQL删除,Lucene的也应该unindex它。

这里是我使用的代码,它试图索引一个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:这个代码是用于测试目的而已,没有必要告诉我,这是多么可怕:)

编辑:

一个解决办法是删除任何previsouly补充说明文件,并编制所有的数据库:

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

我不知道这是最优化的解决方案,是吗?

Answer 1:

只要你让索引/从你的应用程序中单独重建索引来看,你可能会有一个同步的问题。 根据您的工作领域,这可能不是一个问题,但对许多并发用户应用中。

我们有同样的问题时,我们必须运行的异步索引每隔几分钟的作业系统。 用户会发现使用搜索引擎产品,那么即使在管理员从有效的产品堆栈中删除的产品,仍然发现它在前端,直到下一次重建索引作业运行。 这导致报告给第一级的支持非常混乱,罕可再现的错误。

我们看到了两种可能性:要么紧密连接业务逻辑来搜索索引的更新,或执行更严格的异步更新任务。 我们做了后者。

在后台,有一个在tomcat的应用程序需要更新和运行它们并行内部专用线程运行的类。 对于后台更新前端的等待时间下降到0.5-2秒,这大大降低了第一级支持的问题。 而且,它是作为松耦合的就可以了,我们甚至可以实现不同的索引引擎。



Answer 2:

看看Solr的DataImportScheduler方法。
它基本上,一个Web应用程序启动时,产生一个独立的计时器线程,它定期触发HTTP发布针对Solr的,然后使用DataImportHandler设置了从RDB(和其他数据源)中提取数据。

所以,既然你不使用Solr的,只有Lucene的,你应该看一看DataImportHandler源的想法。



文章来源: Index a MySQL database with Apache Lucene, and keep them synchronized