Data Import Handler – import danych z baz SQL (cz. 1)

W artykule o sposobach importu danych (http://solr.pl/2010/09/06/solr-importowanie-danych/) wspomniałem o Data Import Handler (DIH). Podstawową zaletą tego sposobu importowania jest brak konieczności tworzenia dodatkowego oprogramowania oraz szybka integracja ze źródłem danych. Ta druga zaleta wymaga jednak wprawy i praktyki. W tym wpisie przedstawię podstawy integracji DIH ze źródłem danych SQL.

W przykładach użyta została baza PostgeSQL zawierająca dane polskiej wikipedii. Testowa instancja solr została zdefiniowana jako rdzeń „wikipedia” i dostępna była pod adresem:

http://localhost:8983/solr/wikipedia/admin/

Konfiguracja solrconfig.xml

Konfiguracja sprowadza się do dodania dodatkowego requestHandlera. Parametr: config określa plik konfiguracyjny, w którym znajduje się definicja źródła danych.

 <requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
  <lst name="defaults">
   <str name="config">db-data-config.xml</str>
  </lst>
</requestHandler>

Dzięki takiej definicji zyskujemy możliwość wywoływania adresu HTTP obsługującego import:

  • /dataimport – w celu uzyskania aktualnego statusu
  • /dataimport?command=reload-config – w celu ponownego odczytania konfiguracji
  • /dataimport?command=full-import – w celu zlecenia rozpoczęcia pełnego indeksowania danych
  • /dataimport?command=delta-import – w celu zlecenia rozpoczęcia indeksowania przyrostowego

(dla mojej konfiguracji pełen adres to: http://localhost:8983/solr/wikipedia/dataimport)

Powyżej widzimy dwie możliwości importowania danych: import pełny i przyrostowy.

Pełny import danych polega na każdorazowym wczytaniu wszystkich danych, które powinny znaleźć się w indeksie, podczas gdy import przyrostowy oznacza tylko dodanie i aktualizację w indeksie tych danych, które zmieniły się od ostatniego indeksowania. Pełny import zwykle trwa znacznie dłużej stąd prosty wniosek: jeśli czas pełnego indeksowania nie jest dla nas problemem – prawdopodobnie nie warto zawracać sobie głowy konfiguracją indeksowania przyrostowego, zwłaszcza, że nakłada ono  dodatkowe wymagania na strukturę źródła danych.

Warto zaznaczyć, że pełny import domyślnie rozpoczyna się od usunięcia istniejącego indeksu. Istnieje możliwość uniknięcia takiego zachowania poprzez dodanie parametru: clean=false.

Konfiguracja źródła danych

Konfiguracja polega na zdefiniowaniu zapytań pozwalających solr na pobieranie danych do indeksowania i zawiera się w pliku określonym przy definicji handlera (u nas: db-data-config.xml) W tym wpisie zaczniemy od zdefiniowania pełnego importu. Następnie, w kolejnej części artykułu rozbudujemy go o możliwość importowania przyrostowego.

Pełny import

<dataConfig>
  <dataSource driver="org.postgresql.Driver"
     url="jdbc:postgresql://localhost:5432/wikipedia"
     user="wikipedia"
     password="secret" />
  <document>
    <entity name="page" query="SELECT page_id, page_title from page">
      <field column="page_id" name="id" />
      <field column="page_title" name="name" />
      <entity name="revision" query="select rev_id from revision where rev_page=${page.page_id}">
        <entity name="pagecontent" query="select old_text from pagecontent where old_id=${revision.rev_id}">
          <field column="old_text" name="text" />
        </entity>
      </entity>
   </entity>
  </document>
</dataConfig>

Jak widzimy definicja źródła składa się z opisu sposobu połączenia do baz danych oraz opisu indeksowanego dokumentu. Import następuje zgodnie z następującym algorytmem:

  1. Usuwany jest stary indeks (jeśli nie użyto parametru clean=false)
  2. Solr po wywołaniu komendy indeksowania nawiązuje połączenie do bazy danych.
  3. Definiowany jest kursor bazodanowy wykorzystujący zapytanie określone w argumencie „query” w głównej encji
  4. Pobierana jest porcja danych
  5. Dla każdego pobranego rekordu definiowane są zmienne postaci <nazwa encji>.<zwracana kolumna>, dzięki czemu do zwróconych wartości można odwołać się w encjach zagnieżdżonych
  6. Wykonywane są zapytania z encji zagnieżdżonych
  7. Encja może zawierać definicje pól. Dzięki temu Solr jest w stanie określić mapowanie kolumny z wyniku na pole dokumentu zdefiniowane w schema.xml
  8. Dokument stworzony dzięki wartościom zwróconych przez zapytania jest dodawany do indeksu
  9. Jeśli kursor posiada kolejne wyniki następuje skok do punktu 4.
  10. Następuje zapisanie danych do pliku dataimport.properties, dane zostają zatwierdzone (commit) i wykonywana jest optymalizacja indeksu

Po uruchomieniu solr i wejściu na stronę: http://localhost:8983/solr/wikipedia/dataimport pojawiła sie odpowiedź:

<?xml version="1.0" encoding="UTF-8"?>
<response>
  <lst name="responseHeader">
    <int name="status">0</int>
    <int name="QTime">0</int>
  </lst>
  <lst name="initArgs">
    <lst name="defaults">
      <str name="config">db-data-config.xml</str>
    </lst>
  </lst>
  <str name="status">idle</str>
  <str name="importResponse"/>
  <lst name="statusMessages"/>
  <str name="WARNING">This response format is experimental.  It is likely to change in the future.</str>
</response>

Uwagę zwraca wpis: status: idle. Oznacza to, że nasz importer jest gotowy do pracy. W innym przypadku (np. Błąd poprawności XML konfiguracyjnego) dostaniemy opis wyjątku. Niestety na tym etapie nie są wykrywane jeszcze błędy związane np. z niewłaściwą definicją połączenia do bazy lub braku sterownika JDBC.

Wchodzimy więc na stronę: http://localhost:8983/solr/wikipedia/dataimport?command=full-import

To co powinniśmy otrzymać, to podobny jak wyżej XML. Jednak po ponownym wejściu na stronę: http://localhost:8983/solr/wikipedia/dataimport dostajemy już inny wynik.

<?xml version="1.0" encoding="UTF-8"?>
<response>
  <lst name="responseHeader">
    <int name="status">0</int>
    <int name="QTime">0</int>
  </lst>
  <lst name="initArgs">
    <lst name="defaults">
      <str name="config">db-data-config.xml</str>
    </lst>
  </lst>
  <str name="status">busy</str>
  <str name="importResponse">A command is still running...</str>
  <lst name="statusMessages">
    <str name="Time Elapsed">0:1:15.460</str>
    <str name="Total Requests made to DataSource">39547</str>
    <str name="Total Rows Fetched">59319</str>
    <str name="Total Documents Processed">19772</str>
    <str name="Total Documents Skipped">0</str>
    <str name="Full Dump Started">2010-10-03 14:28:00</str>
  </lst>
  <str name="WARNING">This response format is experimental.  It is likely to change in the future.</str>
</response>

Czyli importer pracuje.

Po pewnym czasie, zależnym od ilości indeksowanych danych i szybkości komputera otrzymamy:

<?xml version="1.0" encoding="UTF-8"?>
<response>
  <lst name="responseHeader">
    <int name="status">0</int>
    <int name="QTime">0</int>
  </lst>
  <lst name="initArgs">
    <lst name="defaults">
      <str name="config">db-data-config.xml</str>
    </lst>
  </lst>
  <str name="status">idle</str>
  <str name="importResponse"/>
  <lst name="statusMessages">
    <str name="Total Requests made to DataSource">2118645</str>
    <str name="Total Rows Fetched">3177966</str>
    <str name="Total Documents Skipped">0</str>
    <str name="Full Dump Started">2010-10-03 14:28:00</str>
    <str name="">Indexing completed. Added/Updated: 1059322 documents. Deleted 0 documents.</str>
    <str name="Committed">2010-10-03 14:55:20</str>
    <str name="Optimized">2010-10-03 14:55:20</str>
    <str name="Total Documents Processed">1059322</str>
    <str name="Time taken ">0:27:20.325</str>
  </lst>
  <str name="WARNING">This response format is experimental.  It is likely to change in the future.</str>
</response>

Jak widzimy indeksacja zakończyła się sukcesem.

W kolejnym odcinku spróbujemy dodać możliwość importowania przyrostowego.

This post is also available in: angielski

This entry was posted on poniedziałek, Październik 11th, 2010 at 06:54 and is filed under Solr, Tutorial. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

5 komentarzy to “Data Import Handler – import danych z baz SQL (cz. 1)”

  1. Piotrek Says:

    Chyba najbardziej przydatny artykuł do tej pory! w końcu opisane jak coś zrobić:)
    w cz.2 proponuję rozpatrzyć delta-import i full-import, który działa jak delta-import (ja stosuje ten drugi).

    Pozdrawiam!

  2. negativ Says:

    Dzięki. Mamy w planach eksploatowanie tego tematu, bo raz: to co zostało tutaj napisane, to wierzchołek góry lodowej, a dwa: DIH potrafi czasem zaoszczędzić sporo pracy przy integracji z dostarczycielami treści do wyszukiwania 🙂

  3. Piotrek Says:

    koniecznie trzeba to rozwinąć:) w końcu coś po polsku porządnie napisane o solr:)

  4. Solr.pl – 23.11.2010 | Solr, Lucene i inne Says:

    […] Import Handler – Import danych z baz SQL” (część 1, część 2, część 3) – seria artykułów poświęconych wykorzystaniu Data Import […]

  5. Joanna Says:

    Super blog. Pierwszy raz tu jestem i bardzo mi sie podoba. Bede tu na pewno zagladac i mam nadzieje, ze bedzie systematycznie rozwijany 🙂