2012-05-31 6 views
8
  1. Po dodaniu nowego elementu do MySQL musi on być również zindeksowany przez Lucene.
  2. Kiedy istniejący przedmiot zostanie usunięty z MySQL, musi zostać również usunięty z indeksu Lucene.

Chodzi o to, aby napisać skrypt, który będzie wywoływany co x minut za pośrednictwem terminarza (np. Zadania CRON). Jest to sposób na synchronizację MySQL i Lucene. Do tej pory udało mi się:Indeksuj bazę danych MySQL za pomocą Apache Lucene i synchronizuj je

  1. Za każdy nowy dodany element w MySQL, Lucene również go indeksuje.
  2. Dla każdego już dodanego elementu w MySQL, Lucene nie reindeksuje go (brak duplikatów).

Jest to punkt Pytam ci pomóc w zarządzaniu:

  1. Dla każdego uprzednio dodanego elementu, który został następnie usunięty z MySQL, Lucene powinny również martwi usunięciem go.

Oto kod użyłem, który próbuje indeks tabeli 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: ten kod jest tylko do testów celów, nie ma potrzeby, aby mi powiedzieć, jak straszne jest to :)

EDIT:

Jednym z rozwiązań mogłoby być usunięcia previsouly dodany dokument, a reindex całą bazę danych:

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

Nie jestem pewien, czy jest to najbardziej zoptymalizowane rozwiązanie, prawda?

+0

Co zrobiłeś w końcu? –

Odpowiedz

7

Dopóki pozwolisz, aby indeksowanie/reindeksowanie przebiegało oddzielnie od twojej aplikacji, będziesz mieć problemy z synchronizacją. W zależności od dziedziny pracy może to nie stanowić problemu, ale dla wielu współbieżnych aplikacji użytkownika.

Mieliśmy te same problemy, gdy co kilka minut mieliśmy system pracujący z asynchronicznym indeksowaniem. Użytkownicy mogliby znaleźć produkt za pomocą wyszukiwarki, nawet wtedy, gdy osoba administracyjna usunęła produkt z prawidłowego stosu produktów, nadal znajdowała go w interfejsie, dopóki nie zostanie wykonane kolejne zadanie ponownego indeksowania. Prowadzi to do bardzo mylących i rzadko odtwarzalnych błędów zgłaszanych do wsparcia pierwszego poziomu.

Widzieliśmy dwie możliwości: albo ścisłe powiązanie logiki biznesowej z aktualizacjami indeksu wyszukiwania, albo wdrożenie dokładniejszego asynchronicznego zadania aktualizacji. Zrobiliśmy to drugie.

W tle znajduje się klasa uruchomiona w dedykowanym wątku wewnątrz aplikacji tomcat, która pobiera aktualizacje i uruchamia je równolegle. Czasy oczekiwania na aktualizacje backoffice do frontendu są zmniejszone do 0,5-2 sekund, co znacznie zmniejsza problemy z obsługą pierwszego poziomu. I jest tak luźno sprzężony, jak tylko możemy, możemy nawet zaimplementować inny silnik indeksujący.

1

Proszę spojrzeć na podejście Solr DataImportScheduler.
Zasadniczo, po uruchomieniu aplikacji internetowej, odradza się osobny wątek Timera, który okresowo odpala Post HTTP na Solr, który następnie używa DataImportHandler skonfigurowanego do pobierania danych z RDB (i innych źródeł danych).

Ponieważ nie używasz Solr, tylko Lucene, powinieneś przyjrzeć się pomysłom na DataImportHandler source.

Powiązane problemy