Indeksowanie plików doc, pdf itp, czyli integracja Solr z Tika

W poprzednim artykule podaliśmy podstawowe informację, jak umożliwić przeszukiwanie  zawartości plików binarnych, czyli m.in dokumentów MS Word, PDF czy LibreOffice. Dziś zrobimy to samo, wykorzystując Data Import Handler. Ponieważ parę dni temu pojawiła się nowa wersja serwera SOLR (3.1), poniższe wskazówki bazują na tej wersji. Do prezentacji wykorzystano aplikację „example” – wszystkie poniższe zmiany odnoszą się właśnie do tej aplikacji.

Założenia

Zakładamy, że dane dostępne są w formacie XML i zawierają podstawowe informacje o dokumencie oraz nazwę pliku w którym znajduje się treść dokumentu. Pliki znajdują się w zdefiniowanym katalogu. Przykładowy plik:

<?xml version="1.0" encoding="utf-8"?>
<albums>
    <album>
        <author>John F.</author>
        <title>Life in picture</title>
        <description>1.jpg</description>
    </album>
    <album>
        <author>Peter Z.</author>
        <title>Simple presentation</title>
        <description>2.pptx</description>
    </album>
</abums>

Jak widać dane charakteryzują się tym, że poszczególne elementy nie mają indywidualnego identyfikatora. Ale z tym też sobie poradzimy 🙂
Na początku zmodyfikujemy schemat, dodając definicję pola przechowującego zawartość pliku:

<field name="content" type="text" indexed="true" stored="true" multiValued="true"/>

a w solrconfig.xml dodajemy konfigurację handlera DIH:

   
<requestHandler name="/dataimport">
    <lst name="defaults">
        <str name="config">data-config.xml</str>
    </lst>
</requestHandler>

Ponieważ będziemy wykorzystywać entity processor zawarty w bibliotece extras (TikaEntityProcessor), zmodyfikujemy również linijkę ładującą bibiliotekę DIH:

 <lib dir="../../dist/" regex="apache-solr-dataimporthandler-.*\.jar" />

Kolejnym krokiem jest stworzenie pliku data-config.xml. W naszym przypadku:

<dataConfig>
    <script><![CDATA[
        id = 1;
        function GenerateId(row) {
            row.put('id', (id ++).toFixed());
            return row;
        }       
       ]]></script>
   <dataSource type="BinURLDataSource" name="data"/>
    <dataSource type="URLDataSource" baseUrl="http://localhost/tmp/bin/" name="main"/>
    <document>
        <entity name="rec" processor="XPathEntityProcessor" url="data.xml" forEach="/albums/album" dataSource="main" transformer="script:GenerateId">
            <field column="title" xpath="//title" />
            <field column="description" xpath="//description" />
            <entity processor="TikaEntityProcessor" url="http://localhost/tmp/bin/${rec.description}" dataSource="data">
                <field column="text" name="content" />
                <field column="Author" name="author" meta="true" />
                <field column="title" name="title" meta="true" />
            </entity>
        </entity>
    </document>
</dataConfig>

Generowanie identyfikatora rekordu – skrypty

Pierwszym ciekawym elementem jest wykorzystanie standardowo dostępnego ScriptTransformera w celu wygenerowania identyfikatorów dokumentów. Dzięki metodzie javascript „GenerateId” oraz odwołania do niej (transformer=”script:GenerateId”)każdy rekord będzie dodatkowo ponumerowany. Szczerze mówiąc nie jest to zbyt dobra metoda na radzenie sobie z brakiem identyfikatorów, bo nie pozwala na indeksowanie przyrostowe (nie jesteśmy w stanie rozróżnić poszczególnych wersji rekordu) – użyto jej tutaj tylko i wyłącznie w celu pokazania jak łatwo modyfikować poszczególne rekordy. Jeśli nie lubisz Javascriptu – możesz użyć dowolnego języka skryptowego wspieranego przez Java6.

Wykorzystanie wielu źródeł danych

Drugim ciekawym elementem jest wykorzystanie kilku źródeł danych. Ponieważ nasze metadane są dostępne w pliku XML, konieczne jest pobranie tego pliku. Postępujemy standardowo : definiujemy UrlDataSource a następnie przy pomocy processora XpathEntityProcessor analizujemy przychodzące dane. Ponieważ dodatkowo musimy pobrać binarne załączniki do każdego rekordu, definiujemy dodatkowe źródło:  BinURLDataSource oraz dodatkowe entity, korzystające z procesora  TikaEntityProcessor. Jeszcze tylko powiadomienie entity skąd pobrać plik (atrybut url z odwołaniem się do entity – rodzica) oraz powiadomienie z którego źródła skorzystać (atrybut dataSource). Całość dopełnia lista pól do zindeksowania (dodatkowy atrybut meta oznacza, że dane są pobierane z metadanych pliku).

Dostępne pola

Apache Tika pozwala na pobranie z dokumentu szeregu dodatkowych danych. W przykładzie powyżej skorzystaliśmy tylko z tytułu, autora i treści dokumentu. Pełne informacje o dostępnych polach są zawarte w interfejsach, które są implementowane przez klasę Metadata ( http://tika.apache.org/0.9/api/org/apache/tika/metadata/Metadata.html)a dokładnie w stałych definiowanych w tych interfejsach. W szczególności interesujące są DublinCore i MSOffice

Zakończenie

Po uruchomieniu solr i rozpoczęciu procesu importu (czyli wywołania adresu: http://localhost:8983/solr/dataimport?command=full-import) po krótkiej chwili dokumenty zostają wczytane co powinno być widoczne po zadaniu zapytania:http://localhost:8983/solr/select?q=*:*

This entry was posted on poniedziałek, Kwiecień 4th, 2011 at 07:38 and is filed under Bez kategorii, 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.