9
  1. MySQLに新しいアイテムを追加するときは、Luceneによってインデックスを作成する必要があります。
  2. 既存のアイテムをMySQLから削除する場合は、Luceneのインデックスからも削除する必要があります。

アイデアは、スケジューラー(CRONタスクなど)を介してx分ごとに呼び出されるスクリプトを作成することです。これは、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:このコードはテストのみを目的としています。どれほどひどいのか教えてください:)

編集:

1つの解決策は、以前に追加されたドキュメントを削除し、すべてのデータベースのインデックスを再作成することです。

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

それが最も最適化されたソリューションかどうかはわかりませんね。

4

2 に答える 2

9

インデックス作成/再インデックス作成をアプリケーションとは別に実行する限り、同期の問題が発生します。作業分野によっては、これは問題にならない場合がありますが、多くの同時ユーザーアプリケーションでは問題になります。

数分ごとに非同期インデックス作成を実行しているジョブシステムがある場合にも、同じ問題が発生しました。ユーザーは検索エンジンを使用して製品を検索し、管理者が有効な製品スタックから製品を削除した場合でも、次のインデックス再作成ジョブが実行されるまで、フロントエンドでその製品を検出しました。これにより、非常に紛らわしく、再現性の低いエラーが第1レベルのサポートに報告されます。

2つの可能性がありました。ビジネスロジックを検索インデックスの更新に緊密に接続するか、より緊密な非同期更新タスクを実装するかのいずれかです。後者を行いました。

バックグラウンドでは、Tomcatアプリケーション内の専用スレッドで実行されているクラスがあり、更新を取得して並行して実行します。フロントエンドへのバックオフィス更新の待機時間は0.5〜2秒に短縮され、第1レベルのサポートの問題が大幅に軽減されます。そして、それは可能な限り緩く結合されており、別のインデックスエンジンを実装することもできます。

于 2012-06-01T07:35:20.453 に答える
2

SolrDataImportSchedulerアプローチを見てください。
基本的に、Webアプリケーションが起動すると、別のタイマースレッドが生成され、Solrに対してHTTP Postが定期的に起動されます。次に、Solrは、RDB(およびその他のデータソース)からデータをプルするように設定したDataImportHandlerを使用します。

したがって、Solrを使用しておらず、Luceneのみを使用しているため、 DataImportHandlerソースでアイデアを確認する必要があります。

于 2012-06-01T07:25:47.583 に答える