<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>dev garden &#187; PHP</title>
	<atom:link href="http://darekzon.com/category/php/feed" rel="self" type="application/rss+xml" />
	<link>http://darekzon.com</link>
	<description>when technology meets nature</description>
	<lastBuildDate>Mon, 19 Mar 2012 23:02:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Zend_Tool_Project &#8211; początki Rapid</title>
		<link>http://darekzon.com/2009/06/zend_tool_project-poczatki-rapid</link>
		<comments>http://darekzon.com/2009/06/zend_tool_project-poczatki-rapid#comments</comments>
		<pubDate>Tue, 09 Jun 2009 18:11:09 +0000</pubDate>
		<dc:creator>darek</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[zend tool]]></category>
		<category><![CDATA[zf]]></category>

		<guid isPermaLink="false">http://darekzon.com/?p=254</guid>
		<description><![CDATA[Zend_Tool to narzędzie które wspomóc ma tworzenie szkieletu aplikacji a w zamyśle programistów tego komponentu być może wspomoże tworzenie całej aplikacji.  Jest to odpowiednik aplikacji Bakery znanej z CakePHP, Railsów czy też javovych Grailsów. Brzmi genialnie, w rzeczywistości jeszcze wiele &#8230; <a href="http://darekzon.com/2009/06/zend_tool_project-poczatki-rapid">kontynuuj czytanie <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p><a title="Zend Tool Project" href="http://framework.zend.com/manual/en/zend.tool.project.create-a-project.html" target="_blank">Zend_Tool</a> to narzędzie które wspomóc ma tworzenie szkieletu aplikacji a w zamyśle programistów tego komponentu być może wspomoże tworzenie całej aplikacji.  Jest to odpowiednik aplikacji Bakery znanej z CakePHP, Railsów czy też javovych Grailsów.</p>
<p>Brzmi genialnie, w rzeczywistości jeszcze wiele temu projektowi potrzeba żeby stać się prawdziwym konkurentem dla choćby Bakery. W tej chwili możliwe jest jedynie stworzenie szkieletu projektu, dodanie kontrolerów, akcji i widoków, całą resztę przejmuje programista.</p>
<p>Warto jednak dodać, że jest to świetny start do zbudowania własnej aplikacji, gdyż szkielet wygenerowany przez Zend_Tool oparty jest o nowość w bibliotece czyli Zend_Application (o którym napiszę w przyszłości)</p>
<p>Aplikacja jest prosta w użyciu, wystarczy wpisać <strong>zf.sh (zf.bat dla windows-a)</strong> by naszym oczom ukazała się mała pomoc ze spisem komend jakie aplikacja może wykonać (nie jest ich wiele).</p>
<p><span id="more-254"></span></p>
<h3>Jak zainstalować?</h3>
<p>Teoretycznie instalacja jest trywialna, jednak jak się okazuje nie do końca. Aby projekt Zend_Tool działał u nas poprawnie musimy mieć oczywiście zainstalowane środowisko PHP tak aby system widział wywołanie komendy &#8222;<em><strong>php</strong></em>&#8222;. Następnie pobieramy paczkę ze strony ZendFramework (zawierającą całe ZF) i rozpakowujemy w dowolne miejsce.</p>
<p>Po rozpakowaniu zauważymy, że folder z rozpakowanymi plikami znajduje się folder <strong>bin</strong>. Aby wszystko działało dobrze należy ustawić ścieżkę systemową własnie na ten folder. I to wystarczy, warto jeszcze ustawić w pliku php.ini <strong>include_path</strong> na folder z bibliotekami ZendFramework.</p>
<p>Miłej zabawy</p>
<div class="shr-publisher-254"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://darekzon.com/2009/06/zend_tool_project-poczatki-rapid/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lucynko gdzie są moje klucze cz. 2 &#8211; dbanie o indeks</title>
		<link>http://darekzon.com/2009/05/lucynko-gdzie-sa-moje-klucze-cz-2-dbanie-o-indeks</link>
		<comments>http://darekzon.com/2009/05/lucynko-gdzie-sa-moje-klucze-cz-2-dbanie-o-indeks#comments</comments>
		<pubDate>Mon, 04 May 2009 08:17:30 +0000</pubDate>
		<dc:creator>darek</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[zend search lucene]]></category>

		<guid isPermaLink="false">http://blog.darekzon.com/?p=216</guid>
		<description><![CDATA[W drugiej części postu na temat Zend_Search_Lucene miałem zamiar napisać na temat metod wyszukiwania dokumentów, jednak dostałem wiele zapytań na temat metod dbania o indeks (kasowania oraz edycji dokumentów), jak się okazuje nie jest to do końca proste zadanie, choć &#8230; <a href="http://darekzon.com/2009/05/lucynko-gdzie-sa-moje-klucze-cz-2-dbanie-o-indeks">kontynuuj czytanie <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>W drugiej części postu na temat Zend_Search_Lucene miałem zamiar napisać na temat metod wyszukiwania dokumentów, jednak dostałem wiele zapytań na temat metod dbania o indeks (kasowania oraz edycji dokumentów), jak się okazuje nie jest to do końca proste zadanie, choć mam nadzieje, że po przeczytaniu tego wpisu okaże się to prostsze niż wyglądało na początku.<span id="more-216"></span></p>
<p>Na wstępie przypomnę, że Lucene nie ma możliwości aktualizacji dokumentów które są dodane do indeksu, żeby taką czynność wykonać należy dokument usunąć z indeksu i dodać go na nowo.</p>
<p>Aby indeks działał dobrze warto go porządnie zaprojektować, wystarczy trzymać się poniższej konwencji aby wszystko działało jak należy:</p>
<ol>
<li> wszystkie dane jakie chcecie wyszukiwać, ale nie macie zamiaru wyświetlać w wynikach wyszukiwania najlepiej trzymać w polach typu Unstored pozwoli to zaoszczędzić miejsca dla naszego indeksu, ta także przyśpieszy sam proces indeksowania i wyszukiwania</li>
<li>dane które chcemy przeszukiwać, ale również wyświetlać należy przechowywać w polu typu Text, szczególnie jeśli są to duże partie tekstu</li>
<li>jeśli to możliwe usuwajcie wszelkie html-owe tagi z dokumentu indeksowanego</li>
<li>każdy dokument oznaczcie <strong>unikalnym identyfikatorem</strong> tworzonym według waszego algorytmu, tak abyście mogli łatwo zlokalizować taki dokument, identyfikator trzymajcie w polu typu <strong>Keyword</strong></li>
</ol>
<p>Najważniejszy jest ostatni podpunkt, dzięki niemu będziecie mogli sprawnie operować na indeksie, jak stworzyć taki identyfikator? Ja robię proste złączenie, biorę nazwę tabeli w bazie w której przechowywany jest rekord i łączę go z identyfikatorem rekordu, taki napis dodaję do indeksowanego dokumentu jako pole o nazwie doc i typie <strong><em>Keyword</em></strong></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$dokument</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addField</span><span style="color: #009900;">&#40;</span>Zend_Search_Lucene_Field<span style="color: #339933;">::</span><span style="color: #004000;">keyword</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'doc'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'artykul_'</span><span style="color: #339933;">.</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Dzięki takiemu nazwaniu dokumentu nie muszę martwić się o dwa rekordy o tym samym id ale z różnych tabel, dodatkowo. Jeśli chcecie, możecie nazwę tabeli i rekord zapisać w oddzielnych polach np. <em>doc_id</em>, <em>doc_name</em>, dzięki temu będziecie w stanie usunąć wszystkie dokumenty pochodzące z zadanej tabeli.</p>
<h4>Usuwanie dokumentów</h4>
<p>Jeśli chodzi o samo usuwanie, to polega ono na znalezieniu dokumentu, oznaczeniu go do usunięcia, a następnie usunięciu. Niestety podczas budowania moich indeksów napotkałem się na dziwny błąd, a mianowicie wyszukiwarka nie potrafi poprawnie przeszukać pól typu Keyword z wykorzystaniem najprostszej metody wyszukującej <em>$index->find();</em>.</p>
<p>Rozwiązaniem tego problemu jest wykorzystanie wyszukiwania boolowskiego, dzięki niemu nasza wyszukiwarka jest w stanie znaleźć wartości w polach <strong><em>Keyword</em></strong>.</p>
<p>Kod który poprawnie wyszukuje nasz indeks wygląda następująco:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$term</span>  <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Search_Lucene_Index_Term<span style="color: #009900;">&#40;</span><span style="color: #000088;">$entry</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'doc'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$queryTerm</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Search_Lucene_Search_Query_Term<span style="color: #009900;">&#40;</span><span style="color: #000088;">$term</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$finalQuery</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Search_Lucene_Search_Query_Boolean<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$finalQuery</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addSubquery</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$queryTerm</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$search</span>  <span style="color: #339933;">=</span> <span style="color: #000088;">$index</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$finalQuery</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$search</span> <span style="color: #b1b100;">AS</span> <span style="color: #000088;">$result</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
<span style="color: #000088;">$index</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">delete</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$result</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">id</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000088;">$index</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">commit</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>A teraz linijka po linijce co się tam dzieje.</p>
<ol>
<li>Tworzymy wyrażenie dla indeksu, oraz wskazujemy w które pole ma być przeszukiwane</li>
<li>Na podstawie utworzonego wyrażenia, tworzymy wyrażenie dla zapytania</li>
<li>Tworzymy zapytanie <em>boolowskie</em>, to ono pozwoli nam poprawnie przeszukać pole typu keyword.</li>
<li>Do zapytania boolowskiego podpinamy nasze zapytanie o konkretny dokument.</li>
<li>Wykonujemy zapytanie</li>
<li>Iterujemy po zwróconych wynikach (gdybyśmy np. szukali wszystkich artykułów)</li>
<li>Każdy znaleziony dokument oznaczamy do usunięcia</li>
<li>Potwierdzamy chęć usunięcia dokumentu</li>
</ol>
<pre>* Kod odpowiedzialny za otwarcie indeksu został pominięty</pre>
<p>W ten sposób pozbędziemy się dokumentu który chcemy zaktualizować, po wykonaniu tych czynności możemy bez przeszkód dodać ponownie nasz dokument o czym było w <a title="Lucynko, gdzie są moje klucze? Zend_Search_Lucene. cz. 1" href="http://blog.darekzon.com/2009/03/lucynko-gdzie-sa-moje-klucze-zend_search_lucene-cz-1.html" target="_self">poprzednim wpisie</a></p>
<div class="shr-publisher-216"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://darekzon.com/2009/05/lucynko-gdzie-sa-moje-klucze-cz-2-dbanie-o-indeks/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Lucynko, gdzie są moje klucze? Zend_Search_Lucene. cz. 1</title>
		<link>http://darekzon.com/2009/03/lucynko-gdzie-sa-moje-klucze-zend_search_lucene-cz-1</link>
		<comments>http://darekzon.com/2009/03/lucynko-gdzie-sa-moje-klucze-zend_search_lucene-cz-1#comments</comments>
		<pubDate>Mon, 30 Mar 2009 20:23:40 +0000</pubDate>
		<dc:creator>darek</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[indeksowanie]]></category>
		<category><![CDATA[lucene]]></category>
		<category><![CDATA[wyszukiwanie]]></category>
		<category><![CDATA[zend]]></category>

		<guid isPermaLink="false">http://blog.darekzon.com/?p=121</guid>
		<description><![CDATA[Mając duży portal jasnym staje się, że potrzebna jest wyszukiwarka, która pozwoli w łatwy sposób znaleźć strony które mogą nas interesować. Napisanie wyszukiwarki dla dużej strony nie jest łatwą sprawą, trzeba wziąć pod uwagę, że dane mogą być przechowywane w &#8230; <a href="http://darekzon.com/2009/03/lucynko-gdzie-sa-moje-klucze-zend_search_lucene-cz-1">kontynuuj czytanie <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>Mając duży portal jasnym staje się, że potrzebna jest wyszukiwarka, która pozwoli w łatwy sposób znaleźć strony które mogą nas interesować. Napisanie wyszukiwarki dla dużej strony nie jest łatwą sprawą, trzeba wziąć pod uwagę, że dane mogą być przechowywane w wielu tabelach. Zamiast pisać wielolinijkowe zapytania do bazy danych, zawierające łączenia, unie i inne dziwactwa warto za interesować się indeksowaniem stron. Na rynku od dawna istnieje Xapian, zaawansowany mechanizm indeksowania oraz wyszukiwania napisany w C++ ale oferujący moduł do PHP. Działa świetnie, ale.., wymagane jest za instalowanie specjalnego modułu co jak wiadomo na serwerach hostingowych graniczy z cudem. I tu na pole bitwy wkracza Lucene, system pierwotnie napisany w Javie, udostępniony dla programistów PHP jako moduł Zend_Framework.<span id="more-121"></span></p>
<p>Zend_Search_Lucene bo tak się w pełni nazywa do swojego działania potrzebuje:</p>
<ul>
<li><a title="dokumentacja ctype - php.net " href="http://www.php.net/manual/en/intro.ctype.php" target="_blank">ctype</a> &#8211; sprawdzanie znaków i liczb z wyznaczonymi kryteriami</li>
<li><a title="dokumentacja dom - php.net" href="http://www.php.net/manual/en/ref.dom.php" target="_blank">dom</a> &#8211; obiektowy dostęp do xml-a</li>
<li><a title="dokumentacja iconv - php.net" href="http://www.php.net/manual/en/intro.iconv.php">iconv</a> &#8211; konwersja między systemami kodowania znaków</li>
<li><a title="dokumentacja libxml - php.net" href="http://www.php.net/manual/en/intro.libxml.php" target="_blank">libxml</a> &#8211; obsługa xml-a</li>
<li><a title="strona bitset - php-owa implementacja pecl.php.net" href="http://pecl.php.net/package/Bitset">bitset</a> &#8211; wydajne zbiory dla php &#8211; <strong>nie jest wymagane</strong></li>
</ul>
<p>Powyższe elementy są standardowym wyposażeniem niemal każdego serwera hostingowego w Polsce, więc nie powinniśmy mieć większych problemów z instalacją <a title="dokumentacja - Zend_Search_Lucene" href="http://framework.zend.com/manual/en/zend.search.lucene.html" target="_blank">Zend_Search_Lucene</a> na serwerze (no może poza małą konfiguracją dodatkową, o czym później).</p>
<h3>Co dostaniemy dzięki Zend_Search_Lucene</h3>
<h4>1. Wszystko w jednym miejscu</h4>
<p style="padding-left: 30px;">System indeksujący Lucene trzyma wszystkie dane jakie zindeksował w jednym miejscu, dane z różnych tabel i baz danych, dane z plików, grafiki, można znaleźć wywołując jedno zapytanie.</p>
<h4>2. Łatwe indeksowanie wielu typów danych</h4>
<p style="padding-left: 30px;">System Lucene potrafi zindeksować dowolny rodzaj danych tekstowych jaki mu podamy, co więcej, jest w stanie zindeksować pliki <a title="indeksowanie dokumentów word - dokumentacja" href="http://framework.zend.com/manual/en/zend.search.lucene.html#zend.search.lucene.index-creation.docx-documents" target="_blank">worda</a> (07), <a title="indeksowanie plików excel - dokumentacja" href="http://framework.zend.com/manual/en/zend.search.lucene.html#zend.search.lucene.index-creation.xlsx-documents" target="_blank">excela</a> (07) oraz <a title="indeksowanie prezentacji power point - dokumentacja" href="http://framework.zend.com/manual/en/zend.search.lucene.html#zend.search.lucene.index-creation.pptx-documents" target="_blank">power pointa</a> (07), a także <a title="indeksowanie html-a - dokumentacja" href="http://framework.zend.com/manual/en/zend.search.lucene.html#zend.search.lucene.index-creation.html-documents" target="_blank">strony www</a> (w zasadzie jest to rodzaj pliku tekstowego, ale posiada specjalnie zdefiniowaną do tego klasę).</p>
<h4>3. Jednolite wyniki</h4>
<p style="padding-left: 30px;">Przy dobrze zaprojektowanym indeksie dostajesz zawsze jednolite wyniki, nie musisz sprawdzać czy dane pole istnieje, z jakiego miejsca pochodzą dane, by odpowiednio je pobrać, zawsze wiesz jakie pole przechowuje jakie dane.</p>
<h4>4. Wydajność</h4>
<p style="padding-left: 30px;">O wiele szybciej wyszukać dane z pliku lokalnego niż z bazy danych która może być na innym serwerze, lub mocno obciążona przez innych użytkowników. Indeksy są dodatkowo optymalizowane by wyszukiwanie było maksymalnie wydajne.</p>
<p style="padding-left: 30px;">
<h3>O co się musimy martwić?</h3>
<h4>1. Metoda indeksowania i struktura indeksu</h4>
<p>Wraz z Zend_Search_Lucene dostajemy 2 główne moduły, moduł <strong>indeksowania</strong> oraz moduł <strong>wyszukiwania</strong>. Jednak nie jest to w pełni działająca wyszukiwarka, sami musimy &#8222;zbudować&#8221; index, określić jego strukturę (jakie dane będą indeksowane jaką metodą i pod jakim kluczem zostaną zapisane) , a także napisać funkcje obsługujące wyszukiwarkę (co jednak jest banalnie proste)</p>
<h4>2. Dbanie o aktualność indeksu,</h4>
<p><span style="font-weight: normal;">Aby indeks był zawsze aktualny musimy napisać skrypty które będą dodawać bądź usuwać elementy,  jest to dodatkowy kod który trzeba stworzyć, a gdy dojdą nowe źródła danych zaktualizować.</span></p>
<h4>. Ograniczona wielkość indeksu</h4>
<p><span style="font-weight: normal;">W środowiskach opartych o 32bitowe systemy, Lucene może stworzyć maksymalnie 2GB indeks, jest to co prawda wystarczający rozmiar dla średniej/dużej wielkości serwisu, ale jak wiadomo zdarzają się większe.</span></p>
<h3>Jak indeksować dane?</h3>
<p>Sam proces indeksowania danych jest niemal autonomiczny  i trywialny w rozpisaniu, musimy jedynie wskazać co zindeksować. Brzmi prosto ale ma swój haczyk. Aby nasza wyszukiwarka działała optymalnie i wygodnie dla nas warto wcześniej przygotować listę pól które mają być zindeksowane, które pola chcielibyśmy aby wyszukiwarka dla nas przechowywała w indeksie a które ma tylko przeskanować w poszukiwaniu słów-kluczy. Do tego celu służą metody klasy <a title="Zend_Search_Lucene_Field - API" href="http://framework.zend.com/apidoc/core/Zend_Search_Lucene/Document/Zend_Search_Lucene_Field.html" target="_blank">Zend_Search_Lucene_Field</a>.<br />
Do dyspozycji mamy kilka metod, każda z nich działa w inny sposób, jednak jeśli odpowiednio ich użyjemy stworzony zostanie wydajny indeks. Ważne jest byśmy przechowywali tylko te dane, które potem chcemy wyświetlać w wynikach wyszukiwania, resztę danych możemy jedynie zindeksować. Dzięki samemu indeksowaniu zyskujemy na wielkości indeksu nie tracąc jakości otrzymywanych wyników.</p>
<h4>Co i jak zapamiętywać</h4>
<p>Jak wspomniałem wcześniej Lucene dostarcza metodę indeksowania, a wraz znią kilka typów pól indeksowalnych zawartych w obiekcie Zend_Search_Lucene_Field. Dzięki tym metodą możemy wskazać jakie dane jak mają być dodane do indeksu, a są to odpowiednio:</p>
<ul>
<li><strong>Keyword</strong> &#8211; jest idealnym typem pola do przechowywania typów wyliczeniowych, dane przechowywane w takim polu są przechowywane w bazie danych, a także są indeksowane, nie następuje ich rozbiór na czynniki pierwsze (tokenizacja)</li>
<li><strong>UnIndexed</strong> &#8211; jak sama nazwa wskazuje dane takie nie są indeksowane, nie są również tokenizowane, dane takie natomiast są zachowywane w bazie, jest to bardzo dobry wybór, jeśli chcemy przechowywać adres dokumentu, jego klucz główny w bazie, daty</li>
<li><strong>Text</strong> &#8211; dane są ineksowane, tokenizowane i przechowywane w ineksie, w tym typie pola będziemy przechowywać wszelkie teksty gdyż najczęście na podstawie zawartych w nich słowach będziemy znajdować elementy, jeśli wyniki nie muszą zwracać pełnych wpisów w bazie, to pole może przechowywać tylko krótki opis co zawiera dany rekord</li>
<li><strong>Unstored</strong> &#8211; tak samo jak pole typu <strong>Text</strong> dane są indeksowane i tokenizowane, jednak nie są zapisywane w bazie, idealnie nadaje się do indeksowania długich tekstów, nie musimy martwić się o zbyt duży rozrost naszego indeksu zachowując jednocześnie jakość wyników</li>
<li><strong>Binary</strong> &#8211; ten typ jedynie przechowuje dane, jednak nie są to typowe dane, a dane binarne (np. zdjęcia, pliki tekstowe, muzyka), używać z rozwagą</li>
</ul>
<p>Wszystkie powyższe metody poza metodą <strong>Binary</strong> są trójargumentowe. Pierwszy argument to klucz (nazwa) pola, po nim będziemy się dostawać do wartości jakie on reprezentuje, drugim są same dane przekazane modułowi indeksowania, a ostatni opcjonalny to kodowanie danych które przekazujemy.</p>
<h4>Uwaga!</h4>
<p>Należy pamiętać, że żadne z pól nie może się nazywać &#8222;<em>id</em>&#8221; jest to nazwa zastrzeżona (niestety w dokumentacji nic o tym nie mówią) dla systemu indeksującego.</p>
<h3>Budujemy indeks</h3>
<p>Tyle czytania a jeszcze nie było kodu, czas to zmienić.<br />
Proces indeksowania odbywa się w 4 etapach, w etapie pierwszym tworzymy nowy obiekt <a title="Zend_Search_Lucene_Document - API" href="http://framework.zend.com/apidoc/core/Zend_Search_Lucene/Document/Zend_Search_Lucene_Document.html" target="_blank">Zend_Search_Lucene_Document</a>, następnie (etap 2), dodajemy dane do tego dokumentu, należy również otworzyć indeks (etap 3), by można go było dodać (etap 4) wcześniej stworzony dokument do niego. W kodzie PHP wygląda to następująco:</p>
<pre class="brush: php; title: ; notranslate">
dokument = new Zend_Search_Lucene_Document();
$dokument-&gt;addField(Zend_Search_Lucene_Field::Text('klucz',$dane));
$index = Zend_Search_Lucene::create('/nasz/index');
$index-&gt;addDocument($dokument);&lt;/pre&gt;
</pre>
<p>Prawda, że prosto? Oczywiście indeks taki możemy rozbudować o kolejne pola danych co na pewno rozbuduje nasza wyszukiwarkę.  Jeśli nie mamy jeszcze indeksu należy go stworzyć robimy to poleceniem:</p>
<pre class="brush: php; title: ; notranslate">$index = Zend_Search_Lucene::create('/nasz/index',true);</pre>
<p>Polecenie to tworzy indeks w katalogu &#8221;/nasz/index&#8221;, drugi argument zapewnia nam, że jest to nowy, czysty indeks (jeśli wcześniej istniał tam indeks jest on usuwany.</p>
<p>Indeksowanie wielu dokumentów</p>
<p>Jedyna różnica między indeksowaniem jednego dokumentu a ich całą grupą jest komenda $index-&gt;commit();</p>
<p><span> </span>którą zatwierdza chęć zindeksowania dodanych plików, funkcję tą uzywamy również gdy chcemy usunąć dokument z indeksu.</p>
<pre class="brush: php; title: ; notranslate">
$data = array(array('id'=&gt;1,'title'=&gt;'Tytul1','text'=&gt;'text1'),array('id'=&gt;2,'title'=&gt;'Tytul2','text'=&gt;'Text2');
$infex = Zend_Search_Lucene_Index::open('/moj/index');

foreach($data AS $d){
	$d = new Zend_Search_Lucene_Document();
        $d-&gt;addField(Zend_Search_Lucene_Dokument:: UnStored('doc',$d['id']);
	$d-&gt;addField(Zend_Search_Lucene_Dokument::Text('title',$d['title']);
	$d-&gt;addField(Zend_Search_Lucene_Dokument::Text('text',$d['text']);
	$d-&gt;addField(Zend_Search_Lucene_Dokument::UnIndexed('date',date(&quot;F j, Y, g:i a&quot;));
}
$index-&gt;commit();
</pre>
<p>Warto zauważyć, że pole dla klucza ID jest typu UnStored, dzięki temu nie marnujemy miejsca na niepotrzebne dane (jeśli potrzebujemy wyciągać ID przy wyszukiwaniu pole powinno być typu Text), po drugie zapewniamy sobie możliwość wyciągnięcia wpisu po znanym nam identyfikatorze co umożliwi nam usunięcie danego dokumenut z indeksu.</p>
<h4>Aktualizowanie indeksu</h4>
<p><span> </span>Jeśli indeks nie będzie aktualiwoany to szybko traci on sens, jego wyniki powoli stają się mało jakościowe dla nas jak i dla klienta,warto więc zadbać o aktualizacje danych w indeksie, niestety Lucene nie udostępnia metod które pozwalają na zaktualizowanie zmienionego pola w danym dokumencie jedynym rozwiązaniem jest skaskowanie dokumentu i dodanie go do indeksu jeszcze raz. Aby dany wpis wykasować najlepiej wyszukać dane wpisy po ich unikalnym identyfikatorze (w poprzednim kodzie ten identyfikator miał nazwę &#8222;id&#8221;, a potem iterując po wynikach kasować dokumenty.</p>
<pre class="brush: php; title: ; notranslate">
$results = $index-&gt;find('id:' .$identyfikator);
foreach ($results as $_r) {
    $index-&gt;delete($r-&gt;id);
}
$index-&gt;commit();
</pre>
<p>Powyższy kod znajdzie wszystkie dokumenty reprezentowane przez podany identyfikator i zaznaczy je do usunięcia. Po usunięciu takich wpisów, możemy na nowo dodać nasz dokument.</p>
<h3>Problemy z indeksowaniem na serwerach hostingowych</h3>
<p>Podczas wdrażania jednego z projektów które posiadały powyższy system indeksowania i wyszukiwania napotkałem dość dziwny problem, otóż pomimo, że na 2 komputerach (windows i macos), indeksy tworzyły się poprawnie, tak już na maszynie produkcyjnej nie działały w cale. Okazało się, że problem był w ustawieniach <strong>iconv</strong>, które domyślnie były ustawione na ISO-8859-1 (polski serwer). Jeśli i u was wystąpi problem rozwiązaniem jest dodanie poniższych linijek:</p>
<pre class="brush: php; title: ; notranslate">
setlocale(LC_ALL, 'pl_PL.utf-8');
iconv_set_encoding(&quot;internal_encoding&quot;, &quot;UTF-8&quot;);
iconv_set_encoding(&quot;output_encoding&quot;, &quot;UTF-8&quot;);
iconv_set_encoding(&quot;input_encoding&quot;, &quot;UTF-8&quot;);
</pre>
<h3>Podsumowanie</h3>
<p>Coraz częściej widzimy w serwisach błąd związany z przeciążeniem baz danych, wiąże się to z coraz większym zainteresowaniem młodych ludzi stawianiem for i innych systemów mocno wykorzystujących bazy danych. Dzięki Zend_Search_Lucene i przemyślanemu cache-owaniu, niemal do zera spada wykorzystanie baz danych zapewniając naszej aplikacji internetowej większą stabilność i dostępność. Sam mechanizm ułatwia stworzenie jednolitej wyszukiwarki bez potrzeby martwienia się o optymalizację nieraz skomplikowanych zapytać do bazy danych. Na pewno warto przyjrzeć się temu systemowi a co odważniejsi być może spróbują wdrożyć go w swoich systemach. W drugiej części  opowiem o procesie przeszukiwania indeksu i jego różnych metodach. Zapraszam.</p>
<div class="shr-publisher-121"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://darekzon.com/2009/03/lucynko-gdzie-sa-moje-klucze-zend_search_lucene-cz-1/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

