Pełnotekstowe wyszukiwanie w PHP za pomocą Xapiana
Xapian to biblioteka do pełnotekstowego wyszukiwania danych wykorzystująca własne indeksy. Dzięki rozszerzeniom dostępnym dla wielu języków (PHP, Python, Ruby, Java itd.) można korzystać z tej biblioteki w różnych projektach. Wykorzystywana jest przez Die Zeit, Gmane, serwisy Debiana, czy była/jest wykorzystywana przez del.ico.us. Oferuje bardzo dobrą wydajność i jest mniej wymagająca sprzętowo i aplikacyjne od serwera SOLR.
Główne możliwości i zalety Xapiana to:- Otwarte oprogramowanie na licencji GPL
- Obsługa unikodu, przechowywanie danych w indeksach w kodowaniu utf-8
- Działa na wielu systemach (MS Windows, Linux, Mac OS X, FreeBSD, NetBSD, OpenBSD, Solaris, HP-UX, Tru64, IRIX)
- Napiany w C++ z licznymi rozszerzeniami w innych językach
- Ocena dopasowania wyszukanych wpisów do szukanej frazy
- Przeszukiwanie fraz - użytkownik może szukać wyrazów pojawiających się w określonej frazie
- Operatory boolowskie w wyszukiwanych frazach (np. "programowanie NOT perl")
- Obsługa słowotwórstwa i wykrywanie różnych odmian wyrazów na bazie reguł danego języka (Danish, Dutch, English, Finnish, French, German, Hungarian, Italian, Norwegian, Portuguese, Romanian, Russian, Spanish, Swedish, Turkish)
- Wyszukiwanie z wildcardem xap*n
- Sugerowanie poprawnej pisowni szukanej frazy na podstawie zaindeksowanych wyrazów
- Obsługuje pliki danych większe od 2GB. Format niezależny od systemu operacyjnego
- Obsługa jednoczesnej aktualizacji i wyszukiwania
- Dołączona aplikacja Omega potrafiąca indeksować różne formaty dokumentów: HTML, PHP, PDF, PostScript, OpenOffice/StarOffice, OpenDocument, Microsoft Word/Excel/Powerpoint/Works, Word Perfect, AbiWord, RTF, DVI, Perl POD, jak i dane z dowolnej bazy danych obsługiwanej przez moduł Perla DBI.
Instalacja Xapiana i rozszerzenia PHP
W przypadku dystrybucji Linuksa Xapian powinien być dostępny na liście pakietów. Będziemy potrzebować także pakiet xapian-bindings zawierający rozszerzenie dla PHP (w niektórych dystrybucjach ten pakiet może być rozbity na poszczególne języki, np. xapian-bindings-php). Instalujemy oba pakiety. Następnie do php.ini dodajemy rozszerzenie:
Dla innych systemów, lub dystrybucji nie posiadających Xapiana w repozytoriach pozostają pakiety i źródła ze strony projektu.
Wykorzystanie Xapiana w PHP
Zaprezentuję tutaj dwa proste skrypty do indeksowania i wyszukiwania zaindeksowanych danych. Do ciebie będzie należeć wykorzystanie zaprezentowanego API do indeksowania jakiś rzeczywistych, sensownych danych :) W przygotowaniu jest także nakładkowa biblioteka dla Zend Framework (które będzie opierać się na opisywanym binarnym rozszerzeniu i będzie ono potrzebne). Poniżej zaprezentowałem czyste API Xapiana w PHP.
Indeksowanie danych polega na zapisie odpowiednio obrobionych danych w indeksie Xapiana - zbiorze plików w podanym katalogu. Oto skrypt umożliwiający zaindeksowanie podanej frazy:<?php
include "xapian.php";
try {
// Otwieramy bazę danych lub tworzymy jeżeli nie istnieje
$database = new XapianWritableDatabase('/ścieżka/do/xapian-db', Xapian::DB_CREATE_OR_OPEN);
$indexer = new XapianTermGenerator();
// wybieramy język do słowotwórstwa
$stemmer = new XapianStem("english");
$indexer->set_stemmer($stemmer);
$art = 'To jest jakiś artykuł o PHP';
$doc = new XapianDocument();
$doc->set_data($art);
$indexer->set_document($doc);
$indexer->index_text($art);
// dodajemy dokument do indeksu
$database->add_document($doc);
// zamykamy połączenie z indeksem Xapiana
$database = Null;
print 'Dodane';
} catch (Exception $e) {
print $e->getMessage() . "
";
exit(1);
}
Następnie otwieramy połączenie z indeksem (bazą) Xapiana. Jeżeli baza nie istnieje to zostanie stworzona (wymagane prawa zapisu w katalogu nadrzędnym). Po otworzeniu połączenia z indeksem wybieramy język (w tym przypadku angielski, nie ma niestety oficjalnego polskiego stemmera) i możemy indeksować "dokument", w tym przypadku zwykły łańcuch. Możesz zaindeksować dla testów kilka podobnych fraz.
Wyszukiwanie w Xapianie może przebiegać na wiele sposobów. Poniżej przedstawiłem skrypt wykonujący standardowe wyszukanie najbardziej pasujących dokumentów dla podanej frazy:<?php
include 'xapian.php';
try {
$database = new XapianDatabase('/ścieżka/do/xapian-db');
$enquire = new XapianEnquire($database);
// wyszukiwana fraza
$query_string = 'PHP';
$qp = new XapianQueryParser();
$stemmer = new XapianStem("english");
$qp->set_stemmer($stemmer);
$qp->set_database($database);
$qp->set_stemming_strategy(XapianQueryParser::STEM_SOME);
$query = $qp->parse_query($query_string);
print "Parsed query is: {$query->get_description()}
";
// Zwróć 10 najlepszych wyników
$enquire->set_query($query);
$matches = $enquire->get_mset(0, 10);
// Wyświetl wyniki
print "{$matches->get_matches_estimated()} results found:
";
$i = $matches->begin();
while (!$i->equals($matches->end())) {
$n = $i->get_rank() + 1;
$data = $i->get_document()->get_data();
print "$n: {$i->get_percent()}% docid={$i->get_docid()} [$data]
";
$i->next();
}
} catch (Exception $e) {
print $e->getMessage() . "
";
exit(1);
}
Parsed query is: Xapian::Query(php:(pos=1)) 3 results found: 1: 100% docid=3 [To jest jakiś artykuł‚ o PHP] 2: 92% docid=1 [To jest jakiś artykuł‚ o programowaniu w PHP 1] 3: 92% docid=2 [To jest jakiś artykuł‚ o programowaniu w PHP 2]
Comment article