<?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>import &#8211; Solr.pl</title>
	<atom:link href="https://solr.pl/tag/import/feed/" rel="self" type="application/rss+xml" />
	<link>https://solr.pl</link>
	<description>All things to be found - Blog related to Apache Solr &#38; Lucene projects - https://solr.apache.org</description>
	<lastBuildDate>Wed, 11 Nov 2020 08:15:30 +0000</lastBuildDate>
	<language>pl-PL</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9</generator>
	<item>
		<title>Data Import Handler &#038; XML &#8211; zagnieżdzone encje</title>
		<link>https://solr.pl/2011/03/07/data-import-handler-xml-zagniezdzone-encje/</link>
					<comments>https://solr.pl/2011/03/07/data-import-handler-xml-zagniezdzone-encje/#respond</comments>
		
		<dc:creator><![CDATA[Marek Rogoziński]]></dc:creator>
		<pubDate>Mon, 07 Mar 2011 08:12:53 +0000</pubDate>
				<category><![CDATA[Solr]]></category>
		<category><![CDATA[data import handler]]></category>
		<category><![CDATA[dih]]></category>
		<category><![CDATA[import]]></category>
		<category><![CDATA[solr]]></category>
		<guid isPermaLink="false">http://sematext.solr.pl/?p=205</guid>

					<description><![CDATA[Data Import Handler jest bardzo miłym i rozbudowanym narzędziem. Poniżej opis problemu (i rozwiązania) w którym spotkałem się ostatnio. Opis Problemu Do zaindeksowania jest pewna lista produktów. Produkty jednak mogą być łączone w grupy. Dodatkowo w grupie, w kolejnych elementach]]></description>
										<content:encoded><![CDATA[<p>Data Import Handler jest bardzo miłym i rozbudowanym narzędziem. Poniżej opis problemu (i rozwiązania) w którym spotkałem się ostatnio.</p>
<p><span id="more-205"></span></p>
<h2>Opis Problemu</h2>
<p>Do zaindeksowania jest pewna lista produktów. Produkty jednak mogą być łączone w grupy. Dodatkowo w grupie, w kolejnych elementach mogą być pominięte te dane, które w elemencie wcześniej zostały zdefiniowane. Przykładowa struktura (nieistotne informacje pominąłem dla czytelności):
</p>
<pre class="brush:xml">&lt;products&gt;
  &lt;product&gt;
    &lt;id&gt;1&lt;/id&gt;
    &lt;name&gt;Product 1&lt;/name&gt;
  &lt;/product&gt;
  &lt;product&gt;
    &lt;id&gt;2&lt;/id&gt;
    &lt;name&gt;Product 2&lt;/name&gt;
  &lt;/product&gt;
  &lt;group&gt;
    &lt;product&gt;
      &lt;id&gt;3&lt;/id&gt;
      &lt;name&gt;Product 3 and 4&lt;/name&gt;
    &lt;/product&gt;
    &lt;product&gt;
      &lt;id&gt;4&lt;/id&gt;
    &lt;/product&gt;
  &lt;/group&gt;
&lt;/products&gt;</pre>
<h2>Rozwiązanie</h2>
<p>Rozwiązanie polega na zdefiniowaniu &#8211; jak zawszę &#8211; elementu &#8222;entity&#8221; w sposób następujący:
</p>
<pre class="brush:xml">&lt;entity processor="XPathEntityProcessor"
    forEach="/products/product | /products/group/product"&gt;
  &lt;field column="id" xpath="//id" /&gt;
  &lt;field column="name" xpath="//name" commonField="true" /&gt;
&lt;/entity&gt;</pre>
<h2>Wyjaśnienie</h2>
<p>Dzięki takiej konstrukcji &#8222;forEach&#8221; do przetworzenia dostaną się zarówno produkty nie należące do grupy, jak i te w grupach. Istotnym atrybutem pola jest &#8222;commonField&#8221;. Informuje on DIH, że jeśli w danym rekordzie nie jest zdefiniowane to pole, należy je pobrać z rekordu poprzedniego.</p>
<p>Podane rozwiązanie ma parę ograniczeń, np. pierwszy element w grupie powinien mieć zdefiniowane pole &#8222;name&#8221; oraz ważna jest kolejność produktów, natomiast w moim przypadku pokrywało się to dokładnie ze specyfikacją dostarczonego pliku importu.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://solr.pl/2011/03/07/data-import-handler-xml-zagniezdzone-encje/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Data Import Handler – usuwanie danych z indeksu</title>
		<link>https://solr.pl/2011/01/03/data-import-handler-usuwanie-danych-z-indeksu/</link>
					<comments>https://solr.pl/2011/01/03/data-import-handler-usuwanie-danych-z-indeksu/#respond</comments>
		
		<dc:creator><![CDATA[Marek Rogoziński]]></dc:creator>
		<pubDate>Mon, 03 Jan 2011 07:58:02 +0000</pubDate>
				<category><![CDATA[Solr]]></category>
		<category><![CDATA[baza danych]]></category>
		<category><![CDATA[data import handler]]></category>
		<category><![CDATA[dih]]></category>
		<category><![CDATA[import]]></category>
		<category><![CDATA[integracja]]></category>
		<guid isPermaLink="false">http://sematext.solr.pl/?p=171</guid>

					<description><![CDATA[Usuwanie danych z indeksu przy wykorzystaniu indeksowania przyrostowego w DIH jest na wiki SOLR potraktowane szczątkowo, jako coś, co działa analogicznie do aktualizacji rekordów. Podobnie we wcześniejszym artykule użyłem tego skrótu, tym bardziej, że podany przeze mnie przykład z indeksowaniem]]></description>
										<content:encoded><![CDATA[<p>Usuwanie danych z indeksu przy wykorzystaniu indeksowania przyrostowego w DIH jest na wiki SOLR potraktowane szczątkowo, jako coś, co działa analogicznie do aktualizacji rekordów. Podobnie we wcześniejszym artykule użyłem tego skrótu, tym bardziej, że podany przeze mnie przykład z indeksowaniem zasobów wikipedii nie potrzebował usuwania danych.</p>
<p><span id="more-171"></span></p>
<p>Mając pod ręką przykładowe dane z albumami i wykonawcami postanowiłem pokazać mój sposób postępowania w takich wypadkach. Dla uproszczenia i przejrzystości zakładam, że po pierwszym zaimportowaniu, danych może tylko ubywać.</p>
<h2>Dane testowe</h2>
<p>Moje dane testowe mieszczą się bazie PostgreSQL w tabeli zdefiniowanej następująco:</p>
<pre>Table "public.albums"
Column |  Type   |                      Modifiers
--------+---------+-----------------------------------------------------
id     | integer | not null default nextval('albums_id_seq'::regclass)
name   | text    | not null
author | text    | not null
Indexes:
"albums_pk" PRIMARY KEY, btree (id)</pre>
<p>W tabeli znajduje się 825661 rekordów.</p>
<h2>Instalacja testowa</h2>
<p>Do testów użyłem instancji SOLR posiadającej następującą charakterystykę:</p>
<p>Definicja w schema.xml:</p>
<pre class="brush:xml">&lt;fields&gt;
&lt;field name="id" type="string" indexed="true" stored="true" required="true" /&gt;
&lt;field name="album" type="text" indexed="true" stored="true" multiValued="true"/&gt;
&lt;field name="author" type="text" indexed="true" stored="true" multiValued="true"/&gt;
&lt;/fields&gt;
&lt;uniqueKey&gt;id&lt;/uniqueKey&gt;
&lt;defaultSearchField&gt;album&lt;/defaultSearchField&gt;</pre>
<p>Definicja DIH w solrconfig.xml:</p>
<pre class="brush:xml">&lt;requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler"&gt;
&lt;lst name="defaults"&gt;
&lt;str name="config"&gt;db-data-config.xml&lt;/str&gt;
&lt;/lst&gt;
&lt;/requestHandler&gt;</pre>
<p>I plik DIH db-data-config.xml:</p>
<pre class="brush:xml">&lt;dataConfig&gt;
&lt;dataSource driver="org.postgresql.Driver" url="jdbc:postgresql://localhost:5432/shardtest" user="solr" password="secret" /&gt;
&lt;document&gt;
&lt;entity name="album" query="SELECT * from albums"&gt;
&lt;field column="id" name="id" /&gt;
&lt;field column="name" name="album" /&gt;
&lt;field column="author" name="author" /&gt;
&lt;/entity&gt;
&lt;/document&gt;
&lt;/dataConfig&gt;</pre>
<p>Przed naszym testem zaimportowałem wszystkie dane z tabeli <em>albums</em>.</p>
<h2>Usuwanie danych</h2>
<p>Patrząc na tabelę widać, że gdy usuniemy rekord, ginie on bez śladu i jedynym sposobem aktualizacji naszego indeksu byłoby porównanie identyfikatorów dokumentów w indeksie z identyfikatorami w bazie i wyrzucenie tych, które w bazie już nie istnieją. Wolne i niewygodne. Innym sposobem jest dodatnie kolumny <em>deleted_at</em>: zamiast kasowania fizycznie rekordu, uzupełniamy tylko tę kolumnę. DIH może wtedy pobrać wszystkie rekordy z ustawioną datą późniejszą od ostatniego indeksowania. Wadą tego rozwiązania może by konieczność modyfikacji aplikacji by uwzględniały tak „skasowane” rekordy.</p>
<p>Ja zastosuje inne rozwiązanie, przeźroczyste dla aplikacji. Tworzymy nową tabelę:</p>
<pre class="brush:sql">CREATE TABLE deletes
(
id serial NOT NULL,
deleted_id bigint,
deleted_at timestamp without time zone NOT NULL,
CONSTRAINT deletes_pk PRIMARY KEY (id)
);</pre>
<p>Do tej tabeli automagicznie będziemy dopisywać identyfikatory tych elementów, które zostały usunięte z tabeli <em>albums</em> oraz informacje kiedy zostały usunięte.</p>
<p>Teraz dodamy jeszcze funkcję:</p>
<pre class="brush:sql">CREATE OR REPLACE FUNCTION insert_after_delete()
RETURNS trigger AS
$BODY$BEGIN
IF tg_op = 'DELETE' THEN
INSERT INTO deletes(deleted_id, deleted_at)
VALUES (old.id, now());
RETURN old;
END IF;
END$BODY$
LANGUAGE plpgsql VOLATILE;</pre>
<p>oraz trigger:</p>
<pre class="brush:sql">CREATE TRIGGER deleted_trg
BEFORE DELETE
ON albums
FOR EACH ROW
EXECUTE PROCEDURE insert_after_delete();</pre>
<h2>Sprawdzamy działanie</h2>
<p>Zgodnie z planem, każdy usunięty wpis w tabeli <em>albums</em> powinien skutkować uzupełnieniem tabeli<br /><em>deletes</em>. Sprawdźmy więc. Usuwamy parę rekordów:</p>
<pre class="brush:sql">=&gt; DELETE FROM albums where id &lt; 37;
DELETE 2
=&gt; SELECT * from deletes;
id | deleted_id |         deleted_at
----+------------+----------------------------
26 |         35 | 2010-12-23 13:53:18.034612
27 |         36 | 2010-12-23 13:53:18.034612
(2 rows)</pre>
<p>Czyli baza działa.</p>
<p>Uzupełniamy plik konfiguracyjny DIH tak, by <em>entity</em> było zdefiniowane następująco:</p>
<pre class="brush:xml">&lt;entity name="album" query="SELECT * from albums"
  deletedPkQuery="SELECT deleted_id as id FROM deletes WHERE deleted_at &gt; '$'{dataimporter.last_index_time}'"&gt;</pre>
<p>Dzięki temu przy imporcie przyrostowym DIH użyje atrybutu <em>deletedPkQuery</em> by pobrać identyfikatory tych dokumentów, które należy usunąć.</p>
<p>Sprytny czytelnik pewnie zacznie się zastanawiać, czy na pewno potrzebna jest nam kolumna z datą usunięcia rekordu. Przecież możemy usunąć wszystkie rekordy znalezione w tabeli <em>deleted</em> a następnie skasować zawartość tej tabeli. Teoretycznie to prawda, ale w przypadku problemu z serwerem indeksującym SOLR w naszym wypadku łatwo zastąpić go innym – jego stopień synchronizacji z bazą nie jest bardzo istotny – po prostu za następnym importem przyrostowym nastąpi synchronizacja z bazą. W opcji z kasowaniem zawartości <em>deletes</em> takie możliwości nie ma.</p>
<p>Wykonujemy teraz import przyrostowy wywołując adres: <em>/solr/dataimport?command=delta-import</em><br />W logach powinna pojawić się linia podobna do tej:<br /><em>INFO: {delete=[35, 36],optimize=} 0 2</em><br />Co oznacza, że DIH poprawnie usunął z indeksu te dokumenty, które usunęliśmy wcześniej z bazy.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://solr.pl/2011/01/03/data-import-handler-usuwanie-danych-z-indeksu/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Data Import Handler – import danych z baz SQL (cz. 1)</title>
		<link>https://solr.pl/2010/10/11/data-import-handler-import-danych-z-baz-sql-cz-1/</link>
					<comments>https://solr.pl/2010/10/11/data-import-handler-import-danych-z-baz-sql-cz-1/#respond</comments>
		
		<dc:creator><![CDATA[Marek Rogoziński]]></dc:creator>
		<pubDate>Mon, 11 Oct 2010 04:54:16 +0000</pubDate>
				<category><![CDATA[Solr]]></category>
		<category><![CDATA[baza danych]]></category>
		<category><![CDATA[data import handler]]></category>
		<category><![CDATA[dih]]></category>
		<category><![CDATA[import]]></category>
		<guid isPermaLink="false">http://sematext.solr.pl/?p=40</guid>

					<description><![CDATA[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]]></description>
										<content:encoded><![CDATA[<p>W artykule o sposobach importu danych (<a href="../2010/09/06/solr-importowanie-danych/">http://solr.pl/2010/09/06/solr-importowanie-danych/</a>) wspomniałem o <strong>Data Import Handler</strong> (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.</p>
<p><span id="more-40"></span></p>
<p>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:</p>
<p><a href="http://localhost:8983/solr/wikipedia/admin/">http://localhost:8983/solr/wikipedia/admin/</a></p>
<p><strong>Konfiguracja solrconfig.xml</strong></p>
<p>Konfiguracja sprowadza się do dodania dodatkowego requestHandlera. Parametr: <em>config</em> określa plik konfiguracyjny, w którym znajduje się definicja źródła danych.
</p>
<pre class="brush:xml"> &lt;requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler"&gt;
&nbsp; &lt;lst name="defaults"&gt;
&nbsp;&nbsp; &lt;str name="config"&gt;db-data-config.xml&lt;/str&gt;
&nbsp; &lt;/lst&gt;
&lt;/requestHandler&gt;</pre>
<p>Dzięki takiej definicji zyskujemy możliwość wywoływania adresu HTTP obsługującego import:</p>
<ul>
<li><em>/dataimport</em> &#8211; w celu uzyskania 	aktualnego statusu</li>
<li><em>/dataimport?command=reload-config</em> – w celu ponownego odczytania konfiguracji</li>
<li><em>/dataimport?command=full-import</em> – 	w celu zlecenia rozpoczęcia pełnego indeksowania  danych</li>
<li><em>/dataimport?command=delta-import</em> – 	w celu zlecenia rozpoczęcia indeksowania przyrostowego</li>
</ul>
<p>(dla mojej konfiguracji pełen adres to: http://localhost:8983/solr/wikipedia/dataimport)</p>
<p>Powyżej widzimy dwie możliwości importowania danych: import pełny i przyrostowy.</p>
<p><strong>Pełny import</strong> danych polega na każdorazowym wczytaniu wszystkich danych, które powinny znaleźć się w indeksie, podczas gdy <strong>import przyrostowy</strong> 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&nbsp; dodatkowe wymagania na strukturę źródła danych.</p>
<p>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: <em>clean=false</em>.</p>
<p><strong>Konfiguracja źródła danych</strong></p>
<p>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.</p>
<p><strong>Pełny import</strong>
</p>
<pre class="brush:xml">&lt;dataConfig&gt;
&nbsp; &lt;dataSource driver="org.postgresql.Driver"
&nbsp; &nbsp;&nbsp; url="jdbc:postgresql://localhost:5432/wikipedia"
&nbsp;&nbsp;&nbsp;&nbsp; user="wikipedia"
&nbsp;&nbsp;&nbsp;&nbsp; password="secret" /&gt;
&nbsp; &lt;document&gt;
&nbsp;&nbsp;&nbsp; &lt;entity name="page" query="SELECT page_id, page_title from page"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;field column="page_id" name="id" /&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;field column="page_title" name="name" /&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;entity name="revision" query="select rev_id from revision where rev_page=${page.page_id}"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;entity name="pagecontent" query="select old_text from pagecontent where old_id=${revision.rev_id}"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;field column="old_text" name="text" /&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/entity&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/entity&gt;
&nbsp;&nbsp; &lt;/entity&gt;
&nbsp; &lt;/document&gt;
&lt;/dataConfig&gt;</pre>
<p>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:</p>
<ol>
<li>Usuwany jest stary indeks (jeśli 	nie użyto parametru <em>clean=false</em>)</li>
<li>Solr po wywołaniu komendy 	indeksowania nawiązuje połączenie do bazy danych.</li>
<li>Definiowany jest kursor bazodanowy 	wykorzystujący zapytanie określone w argumencie „<em>query</em>” w 	głównej encji</li>
<li>Pobierana jest porcja danych</li>
<li>Dla każdego pobranego rekordu 	definiowane są zmienne postaci <em>&lt;nazwa encji&gt;.&lt;zwracana 	kolumna&gt;</em>, dzięki czemu do zwróconych wartości można odwołać 	się w encjach zagnieżdżonych</li>
<li>Wykonywane są zapytania z encji 	zagnieżdżonych</li>
<li>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 <em>schema.xml</em></li>
<li>Dokument stworzony dzięki 	wartościom zwróconych przez zapytania jest dodawany do indeksu</li>
<li>Jeśli kursor posiada kolejne 	wyniki następuje skok do punktu 4.</li>
<li>Następuje zapisanie danych do 	pliku dataimport.properties, dane zostają zatwierdzone (<em>commit</em>) i 	wykonywana jest optymalizacja indeksu</li>
</ol>
<p>Po uruchomieniu solr i wejściu na stronę:<a href="http://localhost:8983/solr/wikipedia/dataimport"> http://localhost:8983/solr/wikipedia/dataimport</a> pojawiła sie odpowiedź:
</p>
<pre class="brush:xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;response&gt;
&nbsp; &lt;lst name="responseHeader"&gt;
&nbsp;&nbsp;&nbsp; &lt;int name="status"&gt;0&lt;/int&gt;
&nbsp;&nbsp;&nbsp; &lt;int name="QTime"&gt;0&lt;/int&gt;
&nbsp; &lt;/lst&gt;
&nbsp; &lt;lst name="initArgs"&gt;
&nbsp;&nbsp;&nbsp; &lt;lst name="defaults"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;str name="config"&gt;db-data-config.xml&lt;/str&gt;
&nbsp;&nbsp;&nbsp; &lt;/lst&gt;
&nbsp; &lt;/lst&gt;
&nbsp; &lt;str name="status"&gt;idle&lt;/str&gt;
&nbsp; &lt;str name="importResponse"/&gt;
&nbsp; &lt;lst name="statusMessages"/&gt;
&nbsp; &lt;str name="WARNING"&gt;This response format is experimental.  It is likely to change in the future.&lt;/str&gt;
&lt;/response&gt;</pre>
<p>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.</p>
<p>Wchodzimy więc na stronę:<a href="http://localhost:8983/solr/wikipedia/dataimport?command=full-import"> http://localhost:8983/solr/wikipedia/dataimport?command=full-import</a></p>
<p>To co powinniśmy otrzymać, to podobny jak wyżej XML. Jednak po ponownym wejściu na stronę:<a href="http://localhost:8983/solr/wikipedia/dataimport"> http://localhost:8983/solr/wikipedia/dataimport</a> dostajemy już inny wynik.
</p>
<pre class="brush:xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;response&gt;
&nbsp; &lt;lst name="responseHeader"&gt;
&nbsp;&nbsp;&nbsp; &lt;int name="status"&gt;0&lt;/int&gt;
&nbsp;&nbsp;&nbsp; &lt;int name="QTime"&gt;0&lt;/int&gt;
&nbsp; &lt;/lst&gt;
&nbsp; &lt;lst name="initArgs"&gt;
&nbsp;&nbsp;&nbsp; &lt;lst name="defaults"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;str name="config"&gt;db-data-config.xml&lt;/str&gt;
&nbsp;&nbsp;&nbsp; &lt;/lst&gt;
&nbsp; &lt;/lst&gt;
&nbsp; &lt;str name="status"&gt;busy&lt;/str&gt;
&nbsp; &lt;str name="importResponse"&gt;A command is still running...&lt;/str&gt;
&nbsp; &lt;lst name="statusMessages"&gt;
&nbsp;&nbsp;&nbsp; &lt;str name="Time Elapsed"&gt;0:1:15.460&lt;/str&gt;
&nbsp;&nbsp;&nbsp; &lt;str name="Total Requests made to DataSource"&gt;39547&lt;/str&gt;
&nbsp;&nbsp;&nbsp; &lt;str name="Total Rows Fetched"&gt;59319&lt;/str&gt;
&nbsp;&nbsp;&nbsp; &lt;str name="Total Documents Processed"&gt;19772&lt;/str&gt;
&nbsp;&nbsp;&nbsp; &lt;str name="Total Documents Skipped"&gt;0&lt;/str&gt;
&nbsp;&nbsp;&nbsp; &lt;str name="Full Dump Started"&gt;2010-10-03 14:28:00&lt;/str&gt;
&nbsp; &lt;/lst&gt;
&nbsp; &lt;str name="WARNING"&gt;This response format is experimental.  It is likely to change in the future.&lt;/str&gt;
&lt;/response&gt;</pre>
<p>Czyli importer pracuje.</p>
<p>Po pewnym czasie, zależnym od ilości indeksowanych danych i szybkości komputera otrzymamy:
</p>
<pre class="brush:xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;response&gt;
&nbsp; &lt;lst name="responseHeader"&gt;
&nbsp;&nbsp;&nbsp; &lt;int name="status"&gt;0&lt;/int&gt;
&nbsp;&nbsp;&nbsp; &lt;int name="QTime"&gt;0&lt;/int&gt;
&nbsp; &lt;/lst&gt;
&nbsp; &lt;lst name="initArgs"&gt;
&nbsp;&nbsp;&nbsp; &lt;lst name="defaults"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;str name="config"&gt;db-data-config.xml&lt;/str&gt;
&nbsp;&nbsp;&nbsp; &lt;/lst&gt;
&nbsp; &lt;/lst&gt;
&nbsp; &lt;str name="status"&gt;idle&lt;/str&gt;
&nbsp; &lt;str name="importResponse"/&gt;
&nbsp; &lt;lst name="statusMessages"&gt;
&nbsp;&nbsp;&nbsp; &lt;str name="Total Requests made to DataSource"&gt;2118645&lt;/str&gt;
&nbsp;&nbsp;&nbsp; &lt;str name="Total Rows Fetched"&gt;3177966&lt;/str&gt;
&nbsp;&nbsp;&nbsp; &lt;str name="Total Documents Skipped"&gt;0&lt;/str&gt;
&nbsp;&nbsp;&nbsp; &lt;str name="Full Dump Started"&gt;2010-10-03 14:28:00&lt;/str&gt;
&nbsp;&nbsp;&nbsp; &lt;str name=""&gt;Indexing completed. Added/Updated: 1059322 documents. Deleted 0 documents.&lt;/str&gt;
&nbsp;&nbsp;&nbsp; &lt;str name="Committed"&gt;2010-10-03 14:55:20&lt;/str&gt;
&nbsp;&nbsp;&nbsp; &lt;str name="Optimized"&gt;2010-10-03 14:55:20&lt;/str&gt;
&nbsp;&nbsp;&nbsp; &lt;str name="Total Documents Processed"&gt;1059322&lt;/str&gt;
&nbsp;&nbsp;&nbsp; &lt;str name="Time taken "&gt;0:27:20.325&lt;/str&gt;
&nbsp; &lt;/lst&gt;
&nbsp; &lt;str name="WARNING"&gt;This response format is experimental.  It is likely to change in the future.&lt;/str&gt;
&lt;/response&gt;</pre>
<p>Jak widzimy indeksacja zakończyła się sukcesem.</p>
<p>W kolejnym odcinku spróbujemy dodać możliwość importowania przyrostowego.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://solr.pl/2010/10/11/data-import-handler-import-danych-z-baz-sql-cz-1/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Solr: Importowanie danych</title>
		<link>https://solr.pl/2010/09/06/solr-importowanie-danych/</link>
					<comments>https://solr.pl/2010/09/06/solr-importowanie-danych/#respond</comments>
		
		<dc:creator><![CDATA[Marek Rogoziński]]></dc:creator>
		<pubDate>Mon, 06 Sep 2010 06:02:39 +0000</pubDate>
				<category><![CDATA[Solr]]></category>
		<category><![CDATA[acf]]></category>
		<category><![CDATA[apache connectors framework]]></category>
		<category><![CDATA[cell]]></category>
		<category><![CDATA[import]]></category>
		<category><![CDATA[lcf]]></category>
		<category><![CDATA[nutch]]></category>
		<category><![CDATA[tika]]></category>
		<guid isPermaLink="false">http://sematext.solr.pl/?p=30</guid>

					<description><![CDATA[Solr nie jest przesadnie przyjazny początkującym użytkownikom. Przygotowanie dobrej schemy wymaga pewnego doświadczenia. Zakładając, że mamy już przygotowaną konfigurację, pozostaje nam udostępnienie swoich danych serwerowi wyszukiwania oraz zadbanie o możliwość aktualizacji danych. Sposobów na zaimportowanie danych jest kilka: Update Handler]]></description>
										<content:encoded><![CDATA[<p><!-- 		@page { size: 21cm 29.7cm; margin: 2cm } 		P { margin-bottom: 0.21cm } 		PRE.western { font-family: "DejaVu Sans Mono", monospace; font-size: 10pt } 		PRE.cjk { font-family: "DejaVu Sans", monospace; font-size: 10pt } 		PRE.ctl { font-family: "DejaVu Sans Mono", monospace; font-size: 10pt } 		H2 { margin-bottom: 0.21cm; page-break-after: avoid } 		H2.western { font-family: "Liberation Sans", sans-serif; font-size: 14pt; font-style: italic; font-weight: bold } 		H2.cjk { font-family: "DejaVu Sans"; font-size: 14pt; font-style: italic; font-weight: bold } 		H2.ctl { font-family: "DejaVu Sans"; font-size: 14pt; font-style: italic; font-weight: bold } --><em>Solr</em> nie jest przesadnie przyjazny początkującym użytkownikom. Przygotowanie dobrej schemy wymaga pewnego doświadczenia. Zakładając, że mamy już przygotowaną konfigurację, pozostaje nam udostępnienie swoich danych serwerowi wyszukiwania oraz zadbanie o możliwość aktualizacji danych.</p>
<p><span id="more-30"></span></p>
<p>Sposobów na zaimportowanie danych jest kilka:</p>
<ul>
<li>Update Handler</li>
<li>Cvs Request Handler</li>
<li>Data Import Handler</li>
<li>Extracting Request Handler (Solr 	Cell)</li>
<li>Skorzystać z bibliotek klienckich 	(np. Solrj)</li>
<li>Apache Connectors Framework 	(dawniej Lucene Connectors Framework)</li>
<li>Apache nutch</li>
</ul>
<p>Do tego można jeszcze dodać streaming, jako sposób przesyłania danych. Jak widać, panuje tutaj pewne zamieszanie i ciężko na pierwszy rzut oka podać najlepszą metodę do zastosowania w konkretnym wypadku.</p>
<h2>Update Handler</h2>
<p>Chyba najbardziej popularna metoda, ze względu na prostotę. Wymaga przygotowania odpowiedniego XML oraz przesłanie go poprzez HTTP do serwera Solr. Umożliwia podbijanie ważności dokumentów i pojedynczych pól.</p>
<h2>CSV Request Handler</h2>
<p>W przypadku, gdy dane wejściowe mamy w postaci CSV (Coma Separated Values) lub TSV (Tab Separated Values) ta opcja może być najwygodniejsza. Niestety, w przeciwieństwie do Update Handler, nie ma możliwości podbijania ważności.</p>
<h2>Data Import Handler</h2>
<p>Ta metoda jest mniej popularna, wymaga dodatkowej, czasem dość skomplikowanej konfiguracji, jednak pozwala na bezpośrednie podpięcie się do źródła danych. Dzięki temu nie wymaga żadnych dodatkowych skryptów eksportujących dane ze źródła i konwertujących je na format wymagany przez Solr. Standardowo jest dostępna integracja z bazami danych (w oparciu o JDBC),  źródłami udostępniającymi XML (np. RSS), email (poprzez protokół IMAP), dokumenty obsługiwane przez projekt apache Tika (np. Openoffice,  word, rtf, html i wiele innych). Dodatkowo można dopisywać własne źródła i transformacje.</p>
<h2>Extracting Request Handler (Solr Cell)</h2>
<p>Wyspecjalizowany handler do indeksowania treści dokumentów przechowywanych w plikach o różnych formatach. Lista obsługiwanych formatów jest dość szeroka a do indeksowania wykorzystywany jest projekt apache Tika. Wadą tego rozwiązania jest konieczność budowania dodatkowych rozwiązań dostarczających do SOLR namiary na dokument i informacje o identyfikatorze dokumentu oraz brak możliwości uzupełniania dokumentów o dodatkowe, zewnętrzne względem dokumentu, metadane.</p>
<h2>Biblioteki klienckie</h2>
<p>Solr udostępnia biblioteki klienckie do wielu języków programowania. Ich możliwości różnią się miedzy sobą, natomiast w przypadku, gdy dane są generowane na bieżąco przez aplikację i czas, po którym te dane muszą być dostępne do wyszukiwania jest bardzo mały, indeksowanie w ten sposób często jest jedyną dostępną opcją.</p>
<h2>Apache Connectors Framework</h2>
<p><a title="Apache Connectors Framework (ACF)" href="http://incubator.apache.org/connectors/">ACF</a> jest to relatywnie nowy projekt, który szerszej publiczności objawił się na początku 2010 roku. Projekt początkowo był wewnętrznym projektem prowadzonym przez firmę MetaCarta, został przekazany społeczności open source i w chwili obecnej rozwijany w ramach inkubatora apache. W założeniu jest to system, który dzięki szeregowi wtyczek pozwala „wyklikać” połączenie ze źródłem danych. W chwili obecnej brak jest opublikowanych wersji, ale sam system już warty jest zainteresowania w przypadku konieczności integracji z takimi systemami jak: FileNet P8 (IBM), Documentum (EMC), LiveLink (OpenText), Patriarch (Memex), Meridio (Autonomy), Windows shares (Microsoft) i SharePoint (Microsoft).</p>
<h2>Apache nutch</h2>
<p><a title="Apache Nutch" href="http://nutch.apache.org/">Nutch</a> to zasadzie to oddzielny projekt prowadzony przez Apache (wcześniej w ramach Apache Lucene). Dla osoby zajmującej się serwerem Solr jest on o tyle ciekawy, że pozwala na taką konfigurację, która umożliwia pobieranie stron WWW i indeksowanie ich poprzez Solr.</p>
<h2>Słowo o streamingu</h2>
<p>Streaming oznacza możliwość powiadomienia Solr,&nbsp; skąd pobrać dane do zindeksowania. Pozwala to na uniknięcie zbędnego przesyłania danych przez sieć, jeśli dane znajdują się na zasobie lokalnym względem serwera indeksującego, lub podwójnego przesyłania danych (ze źródła do importera, z importera do Solra).</p>
<h2>I słowo o bezpieczeństwie</h2>
<p>Solr z założenia jest przewidziany do stosowania w architekturze zakładającej pracę w środowisku bezpiecznym. <strong>Bardzo ważne</strong> jest jednak zwrócenie uwagi na to, kto i jakie polecenia jest w stanie wykonywać. O ile zwracane dane można w miarę prosto ograniczyć, poprzez wymuszenie stosowania filtrów w definicji handlerów, o tyle w przypadku indeksowania nie jest to już takie proste. W szczególności niebezpieczny wydaje się być Solr Cell – nie tylko pozwoli na odczytanie dowolnego pliku, do którego ma dostęp Solr (np. pliki z hasłami), ale dodatkowo da możliwość atakującemu na ich wygodne przeszukiwanie w celu uzyskania przydatnych informacji <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<h2>Inne opcje</h2>
<p>Powyżej starałem się uwzględnić opcje, które nie wymagają dodatkowej pracy. Problemem może być definicja tej dodatkowej pracy, bo czasem łatwiej napisać dodatkową wtyczkę, niż przebijać się przez niezliczone opcje konfiguracyjne czy tworzyć gigantyczne XMLe. Dlatego też w wyborze metod kierowałem się własnym wyczuciem, co skutkowało pominięciem kilku sposobów (np. pobieranie danych ze stron WWW za pomocą Apache Droids lub Heritrixa, czy rozwiązania oparte o Open Pipeline lub Open Pipe).</p>
<p>Na pewno w tym krótkim artykule udało mi się pominąć jakieś ciekawe sposoby. Jeśli tak, proszę o komentarze, chętnie uaktualnię ten wpis <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
					
					<wfw:commentRss>https://solr.pl/2010/09/06/solr-importowanie-danych/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
