<?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>faceting &#8211; Solr.pl</title>
	<atom:link href="https://solr.pl/tag/faceting/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>Fri, 13 Nov 2020 21:20:33 +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>Solr 5.1: Nowe API facetingu (szybkie spojrzenie)</title>
		<link>https://solr.pl/2015/05/30/solr-5-1-nowe-api-facetingu-szybkie-spojrzenie/</link>
					<comments>https://solr.pl/2015/05/30/solr-5-1-nowe-api-facetingu-szybkie-spojrzenie/#respond</comments>
		
		<dc:creator><![CDATA[Rafał Kuć]]></dc:creator>
		<pubDate>Sat, 30 May 2015 20:20:03 +0000</pubDate>
				<category><![CDATA[Solr]]></category>
		<category><![CDATA[5.1]]></category>
		<category><![CDATA[faceting]]></category>
		<category><![CDATA[solr]]></category>
		<guid isPermaLink="false">http://sematext.solr.pl/?p=660</guid>

					<description><![CDATA[Wraz z niedawną premierą Solr 5.1 doczekaliśmy się szeregu nowości. Jedną z nich jest przepisany moduł facetingu umożliwiający konstruowanie zapytań w oparciu o format JSON. W niniejszym wpisie postaram się pokrótce przyjrzeć tej funkcjonlaności i zobaczyć, jak Solr zmienia się]]></description>
										<content:encoded><![CDATA[<p>Wraz z niedawną <a title="Lucene i Solr 5.1" href="http://solr.pl/2015/04/14/lucene-i-solr-5-1/">premierą Solr 5.1</a> doczekaliśmy się szeregu nowości. Jedną z nich jest przepisany moduł facetingu umożliwiający konstruowanie zapytań w oparciu o format JSON. W niniejszym wpisie postaram się pokrótce przyjrzeć tej funkcjonlaności i zobaczyć, jak Solr zmienia się jako narzędzie do analizy danych w czasie rzeczywistym.</p>
<p><span id="more-660"></span></p>
<h3>Dane testowe</h3>
<p>Do naszych testów wykorzystamy dane dostarczane wraz z domyślną dystrybucją Solr. Do uruchomienia Solr wykorzystujemy komendę:</p>
<pre class="brush:xml">bin/solr start -e techproducts
</pre>
<p>Spowoduje to uruchomienie Solr oraz zaindeksowanie przykładowych danych &#8211; wszystko to w kolekcji <em>techproducts</em>.</p>
<h3>Przykład pierwszy</h3>
<p>Zacznijmy od bardzo prostego przykładu z wykorzystaniem nowego facetingu &#8211; spróbujmy pobrać od Solr faceting dotyczący producentów oraz kategorii naszych produktów. Zapytanie, do którego jesteśmy przezwyczajeni wyglądało by następująco:</p>
<pre class="brush:xml">curl 'localhost:8983/solr/techproducts/select?q=*:*&amp;rows=0&amp;indent=true&amp;facet=true&amp;facet.field=manu_id_s&amp;facet.field=cat'
</pre>
<p>Zapytanie wykorzystujące nowe API wygląda następująco:</p>
<pre class="brush:xml">curl http://localhost:8983/solr/techproducts/query -d 'q=*:*&amp;rows=0&amp;
 json.facet={
  categories : {
   terms : {
    field: cat
   }
  },
  producers : {
   terms : {
    field: manu_id_s
   }
  }
 }'
</pre>
<p>Odpowiedź na powyższe zapytanie wygląda następująco:</p>
<pre class="brush:xml">{
&nbsp; "responseHeader":{
&nbsp;&nbsp;&nbsp; "status":0,
&nbsp;&nbsp;&nbsp; "QTime":2,
&nbsp;&nbsp;&nbsp; "params":{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "q":"*:*",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "json.facet":"{\n&nbsp; categories : {\n&nbsp;&nbsp; terms : {\n&nbsp;&nbsp;&nbsp; field: cat\n&nbsp;&nbsp; } \n&nbsp; },\n&nbsp; manu : {\n&nbsp;&nbsp; terms : {\n&nbsp;&nbsp;&nbsp; field: manu_id_s\n&nbsp;&nbsp; }\n&nbsp; }\n}",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "rows":"0"}},
&nbsp; "response":{"numFound":32,"start":0,"docs":[]
&nbsp; },
&nbsp; "facets":{
&nbsp;&nbsp;&nbsp; "count":32,
&nbsp;&nbsp;&nbsp; "categories":{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "buckets":[{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "val":"electronics",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "count":12},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "val":"currency",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "count":4},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "val":"memory",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "count":3},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "val":"connector",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "count":2},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "val":"graphics card",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "count":2},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "val":"hard drive",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "count":2},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "val":"search",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "count":2},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "val":"software",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "count":2},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "val":"camera",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "count":1},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "val":"copier",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "count":1}]},
&nbsp;&nbsp;&nbsp; "manu":{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "buckets":[{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "val":"corsair",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "count":3},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "val":"belkin",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "count":2},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "val":"canon",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "count":2},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "val":"apple",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "count":1},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "val":"asus",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "count":1},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "val":"ati",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "count":1},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "val":"boa",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "count":1},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "val":"dell",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "count":1},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "val":"eu",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "count":1},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "val":"maxtor",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "count":1}]}}}
</pre>
<p>Jak widać samo zapytanie, jak i odpowiedź jest czymś do czego nie jesteśmy przezwyczajeni w pracy z Solr. Zacznijmy więc od zapytania.</p>
<h4>Zapytanie</h4>
<p>Tym razem zapytanie wysłaliśmy do handlera <em>query</em>, ale nie to jest ważne. Najważniejsze jest to, jak wygląda samo zapytanie. Wszystkie parametry zapytania nie zostały przekazane jako parametry rządania HTTP. Tym razem wszystkie parametry zostały przekazane w ciele rządania w formie podobnej do tego do czego jesteśmy przezwyczajeni. Oprócz tego dodaliśmy nowy parametr &#8211; <em>facet.json</em>, gdzie zdefiniowaliśmy nasz faceting.</p>
<p>W Solr 5.1, każdy faceting, jaki chcemy wykonać definiujemy następująco:</p>
<pre class="brush:xml">NAZWA: {
 TYP: {
  PARAMETR: WARTOSC
  ...
  PARAMETR: WARTOSC
 }
}
</pre>
<p>W Solr 5.2, ten format zmieni się delikatnie, ale wrócimy do tego, jak tylko pojawi się Solr 5.2. W naszym przykładzie wykorzystaliśmy typ <em>terms</em>, który funkcjonuje tak samo, jak zachowanie znane nam, gdy korzystaliśmy z <em>facet.field</em>. Inne typy to np. <em>query</em>, czy <em>range</em>. Po możliwe do wykorzystania parametry odsyłamy do oficjalnej dokumentacji Solr.</p>
<h4>Wyniki</h4>
<p>Jeżeli natomiast spojrzymy na wyniki zwrócone przez Solr widzimy coś co nazywa się <em>buckets</em>. Są to grupy klucz &#8211; wartość opisujące nasz faceting &#8211; niby coś nowego, ale jednak znajome. Korzystając z nowego API facetingu możemy spotkać się z dwoma rodzajami zwracanych wyników &#8211; pojedyńczą wartością oraz właśnie bucketami. Opiszemy to dokładniej w chwili premiery Solr 5.2.</p>
<h3>Facting i funkcje</h3>
<p>Sprawdźmy jeszcze jeden przypadek &#8211; znalezienie średniej ceny produktów oraz 99 percentyla ceny. Solr umożliwia skorzytanie z szeregu funkcji w ramach nowego modułu facetingu, a zapytanie które umożliwi nam realizację naszego celu wygląda następująco:</p>
<pre class="brush:xml">curl http://localhost:8983/solr/techproducts/query -d 'q=*:*&amp;rows=0&amp;
 json.facet={
  average:"avg(price)",
  percentile:"percentile(price,99)"
 }'
</pre>
<p>Wynik zapytania wygląda następująco:</p>
<pre class="brush:xml">{
&nbsp; "responseHeader":{
&nbsp;&nbsp;&nbsp; "status":0,
&nbsp;&nbsp;&nbsp; "QTime":2,
&nbsp;&nbsp;&nbsp; "params":{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "q":"*:*",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "json.facet":"{\n&nbsp; average:\"avg(price)\",\n&nbsp; percentile:\"percentile(price,99)\"\n }",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "rows":"0"}},
&nbsp; "response":{"numFound":32,"start":0,"docs":[]
&nbsp; },
&nbsp; "facets":{
&nbsp;&nbsp;&nbsp; "count":32,
&nbsp;&nbsp;&nbsp; "average":164.10218846797943,
&nbsp;&nbsp;&nbsp; "percentile":1966.6484985351556}}
</pre>
<p>Solr zwrócił to co chcieliśmy, a Solr zwrócił pojedyncze wartości dla każdej z funkcji.</p>
<h3>Co dalej?</h3>
<p>Oczywiście to nie wszystko co Solr oferuje nam w tym momencie oraz co planowane jest w przyszłości. Po pierwsze ilość funkcji zostanie rozszerzona &#8211; np. o możliwość pobierania unikalnych wartości. Dodatkowo, w Solr 5.2, dostaniemy możliwość zagnieżdżania facetingu i genrowania wyników zapytań zwracających np. minimalne wartości, dla każdej z grup kategorii zwróconej przez <em>terms</em> faceting.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://solr.pl/2015/05/30/solr-5-1-nowe-api-facetingu-szybkie-spojrzenie/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Autocomplete na polach wielowartościowych (faceting)</title>
		<link>https://solr.pl/2013/03/25/autocomplete-na-polach-wielowartosciowych-faceting/</link>
					<comments>https://solr.pl/2013/03/25/autocomplete-na-polach-wielowartosciowych-faceting/#respond</comments>
		
		<dc:creator><![CDATA[Rafał Kuć]]></dc:creator>
		<pubDate>Mon, 25 Mar 2013 11:08:05 +0000</pubDate>
				<category><![CDATA[Solr]]></category>
		<category><![CDATA[autocomplete]]></category>
		<category><![CDATA[faceting]]></category>
		<guid isPermaLink="false">http://sematext.solr.pl/?p=501</guid>

					<description><![CDATA[W poprzednim artykule opisującym możliwe podejście do funkcjonalności autocomplete na polach wielowartościowych skorzystaliśmy z highlightingu, aby wydobyć te informacje, które nas interesowały. Obiecaliśmy także, że wrócimy do tematu i pokażemy, jak osiągnąć podobny efekt z wykorzystaniem facetingu. Zatem, spójrzmy jak]]></description>
										<content:encoded><![CDATA[<p>W <a href="http://solr.pl/2013/02/25/autocomplete-na-polach-wielowartosciowych-highlighting/">poprzednim</a> artykule opisującym możliwe podejście do funkcjonalności autocomplete na polach wielowartościowych skorzystaliśmy z highlightingu, aby wydobyć te informacje, które nas interesowały. Obiecaliśmy także, że wrócimy do tematu i pokażemy, jak osiągnąć podobny efekt z wykorzystaniem facetingu. Zatem, spójrzmy jak wygląda realizacja takiej funkcjonalności.</p>
<p><span id="more-501"></span></p>
<h2>Kilka słów na początek</h2>
<p>Ze względu na to, że jest to niejako kontynuacja poprzedniego wpisu, sugerujemy, aby przeczytać wpis &#8222;<a href="http://solr.pl/2013/02/25/autocomplete-na-polach-wielowartosciowych-highlighting/"><em>Autocomplete na polach wielowartościowych (highlighting)</em></a>&#8222;, aby wszystkie elementy wpisu były jasne. Warto także wspomnieć, iż metoda ta była już pokazywana we wpisie &#8222;<a href="http://solr.pl/2010/10/18/solr-i-autocomplete-cz-1/">Solr i autocomplete (cz. 1)</a>&#8222;, aczkolwiek chcieliśmy przypomnieć ten temat ze względu na częstotliwość pojawiających się pytań.</p>
<h2>Konfiguracja</h2>
<p>Podobnie, jak w poprzednim wpisie zacznijmy od konfiguracji.</p>
<h3>Struktura indeksu</h3>
<p>Struktura naszego indeksu nie różni się od tego co zaprezentowane było w poprzednim wpisie. Jednak, przypomnijmy te informacje &#8211; zakładamy, że chcemy podpowiadać frazy z indeksu z pola wielowartościowego. Pole to nazywa się <em>features</em>, a cała konfiguracja pól w indeksie będzie następująca:
</p>
<pre class="brush:xml">&lt;fields&gt;
 &lt;field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" /&gt;
 &lt;field name="features" type="string" indexed="true" stored="true" multiValued="true"/&gt;
 &lt;field name="features_autocomplete" type="text_autocomplete" indexed="true" stored="true" multiValued="true"/&gt;

 &lt;field name="_version_" type="long" indexed="true" stored="true"/&gt;
&lt;/fields&gt;</pre>
<p>Do autocomplete będziemy wykorzystywać pole <em>features_autocomplete</em>.</p>
<h3>Kopiowanie</h3>
<p>Dodatkowo, aby automatycznie zasilać danymi pole <em>features_autocomplete</em> skorzystamy z funkcjonalności copy field, a zatem do pliku <em>schema.xml</em> dodajemy następujący wpis:
</p>
<pre class="brush:xml">&lt;copyField source="features" dest="features_autocomplete"/&gt;</pre>
<h3>Typ text_autocomplete</h3>
<p>Typ <em>text_autocomplete</em> różni się od tego, co widzieliśmy w poprzednim wpisie. Tym razem wygląda on następująco:
</p>
<pre class="brush:xml">&lt;fieldType name="text_autocomplete" class="solr.TextField" positionIncrementGap="100"&gt;
 &lt;analyzer&gt;
  &lt;tokenizer class="solr.KeywordTokenizerFactory"/&gt;
  &lt;filter class="solr.LowerCaseFilterFactory"/&gt;
 &lt;/analyzer&gt;
&lt;/fieldType&gt;</pre>
<p>Ze względu na to, że będziemy korzystać z facetingu korzystamy z <em>solr.KeywordTokenizerFactory</em> oraz sprawiamy, aby wszystkie znaki były małe za pomocą <em>solr.LowerCaseFilterFactory</em>.</p>
<h3>Przykładowe dane</h3>
<p>Nasze dane są identyczne do tych, które wykorzystaliśmy w poprzednim wpisie i wyglądają następująco:
</p>
<pre class="brush:xml">&lt;add&gt;
 &lt;doc&gt;
  &lt;field name="id"&gt;1&lt;/field&gt;
  &lt;field name="features"&gt;Multiple windows&lt;/field&gt;
  &lt;field name="features"&gt;Single door&lt;/field&gt;
 &lt;/doc&gt;
 &lt;doc&gt;
  &lt;field name="id"&gt;2&lt;/field&gt;
  &lt;field name="features"&gt;Single window&lt;/field&gt;
  &lt;field name="features"&gt;Single door&lt;/field&gt;
 &lt;/doc&gt;
 &lt;doc&gt;
  &lt;field name="id"&gt;3&lt;/field&gt;
  &lt;field name="features"&gt;Multiple windows&lt;/field&gt;
  &lt;field name="features"&gt;Multiple doors&lt;/field&gt;
 &lt;/doc&gt;
&lt;/add&gt;</pre>
<h2>Zapytanie z facetingiem</h2>
<p>Zobaczmy zatem, jak wyglądać będzie nasze zapytanie, kiedy wykorzystamy faceting.</p>
<h3>Pełne zapytanie</h3>
<p>W przypadku facetingu nasze zapytanie powinno wyglądać następująco:
</p>
<pre class="brush:xml">q=*:*&amp;rows=0&amp;facet=true&amp;facet.field=features_autocomplete&amp;facet.prefix=sing</pre>
<p>Kilka słów o dodanych parametrach:</p>
<ul>
<li><em>rows=0</em> &#8211; informujemy Solr, że nie jesteśmy zainteresowani wynikami wyszukiwania,</li>
<li><em>facet=true</em> &#8211; informujemy Solr, iż chcemy korzystać z facetingu,</li>
<li><em>facet.field=features_autocomplete</em> &#8211; określamy jakie pole ma zostać wykorzystane do facetingu,</li>
<li><em>facet.prefix=sing</em> &#8211; za pomocą tego parametru przekazujemy interesującą nas frazę.</li>
</ul>
<h3>Wyniki</h3>
<p>Wyniki, które Solr zwraca na powyższe zapytanie, wyglądają następująco:
</p>
<pre class="brush:xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;response&gt;
&lt;lst name="responseHeader"&gt;
&nbsp; &lt;int name="status"&gt;0&lt;/int&gt;
&nbsp; &lt;int name="QTime"&gt;0&lt;/int&gt;
&nbsp; &lt;lst name="params"&gt;
&nbsp;&nbsp;&nbsp; &lt;str name="facet"&gt;true&lt;/str&gt;
&nbsp;&nbsp;&nbsp; &lt;str name="q"&gt;*:*&lt;/str&gt;
&nbsp;&nbsp;&nbsp; &lt;str name="facet.prefix"&gt;sing&lt;/str&gt;
&nbsp;&nbsp;&nbsp; &lt;str name="facet.field"&gt;features_autocomplete&lt;/str&gt;
&nbsp;&nbsp;&nbsp; &lt;str name="rows"&gt;0&lt;/str&gt;
&nbsp; &lt;/lst&gt;
&lt;/lst&gt;
&lt;result name="response" numFound="3" start="0"&gt;
&lt;/result&gt;
&lt;lst name="facet_counts"&gt;
&nbsp; &lt;lst name="facet_queries"/&gt;
&nbsp; &lt;lst name="facet_fields"&gt;
&nbsp;&nbsp;&nbsp; &lt;lst name="features_autocomplete"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;int name="single door"&gt;2&lt;/int&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;int name="single window"&gt;1&lt;/int&gt;
&nbsp;&nbsp;&nbsp; &lt;/lst&gt;
&nbsp; &lt;/lst&gt;
&nbsp; &lt;lst name="facet_dates"/&gt;
&nbsp; &lt;lst name="facet_ranges"/&gt;
&lt;/lst&gt;
&lt;/response&gt;</pre>
<p>Jak widać, w sekcji odpowiedzialnej za faceting, otrzymaliśmy te frazy, które nas interesowały wraz z ilością dokumentów w jakich się znajdują.</p>
<h3>O czym pamiętać</h3>
<p>Ważną rzeczą jest to, że wartości parametru <em>facet.prefix</em> nie są analizowane, zatem jeżeli zamiast frazy <em>sing</em> przekazalibyśmy frazę <em>Sing</em> Solr nie zwróciłby interesujących nas wyników. Należy o tym pamiętać.</p>
<h2>Podsumowanie</h2>
<p>Powyższy wpis pokazał drugi sposób podejścia do realizacji funkcjonalności autocomplete na polach wielowartościowych. Oczywiście nie wyczerpaliśmy tematu i kiedyś do niego wrócimy, ale na dzisiaj to wszystko. Mamy nadzieję, że komuś się przyda to co znalazł w tych artykułach <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/2013/03/25/autocomplete-na-polach-wielowartosciowych-faceting/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Solr i autocomplete (cz. 1)</title>
		<link>https://solr.pl/2010/10/18/solr-i-autocomplete-cz-1/</link>
					<comments>https://solr.pl/2010/10/18/solr-i-autocomplete-cz-1/#respond</comments>
		
		<dc:creator><![CDATA[Rafał Kuć]]></dc:creator>
		<pubDate>Mon, 18 Oct 2010 05:02:00 +0000</pubDate>
				<category><![CDATA[Solr]]></category>
		<category><![CDATA[autcomplete]]></category>
		<category><![CDATA[faceting]]></category>
		<category><![CDATA[podpowiadanie]]></category>
		<category><![CDATA[solr]]></category>
		<guid isPermaLink="false">http://sematext.solr.pl/?p=44</guid>

					<description><![CDATA[Niemal każdy z nas widział jak wygląda funkcjonalność autocomplete, czyli podpowiadanie użytkownikowi wyrazów lub całych fraz wyszukiwania. Nic dziwnego więc, że także Solr udostępnia mechanizmy przy pomocy których możemy zbudować takie funkcjonalności. W dzisiejszym wpisie pokażę w jaki sposób można]]></description>
										<content:encoded><![CDATA[<p>Niemal każdy z nas widział jak wygląda funkcjonalność <em>autocomplete</em>, czyli podpowiadanie użytkownikowi wyrazów lub całych fraz wyszukiwania. Nic dziwnego więc, że także Solr udostępnia mechanizmy przy pomocy których możemy zbudować takie funkcjonalności. W dzisiejszym wpisie pokażę w jaki sposób można zbudować podpowiadanie przy pomocy facetingu.</p>
<p><span id="more-44"></span></p>
<h3><img fetchpriority="high" decoding="async" class="size-full wp-image-483" title="Google Autocomplete" src="http://solr.pl/wp-content/uploads/2010/10/google_autocomplete2.png" alt="" width="641" height="159"></h3>
<h3>Indeks</h3>
<p>Załóżmy, że chcemy podpowiadać użytkownikowi nazwy produktów w sklepie internetowym. Załóżmy, że nasz indeks składa się z następujących pól:
</p>
<pre class="brush:xml">&lt;field name="id" type="string" indexed="true" stored="true" multiValued="false" required="true"/&gt;
&lt;field name="name" type="text" indexed="true" stored="true" multiValued="false" /&gt;
&lt;field name="description" type="text" indexed="true" stored="true" multiValued="false" /&gt;</pre>
<p>A typ <em>text </em>zdefiniowany jest w następujący sposób:
</p>
<pre class="brush:xml">&lt;fieldType name="text" class="solr.TextField" positionIncrementGap="100"&gt;&nbsp;
 &lt;analyzer&gt;
&nbsp; &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
&nbsp; &lt;filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1"/&gt;&nbsp;
&nbsp; &lt;filter class="solr.LowerCaseFilterFactory"/&gt;
 &lt;/analyzer&gt;
&lt;/fieldType&gt;</pre>
<h3>Konfiguracja</h3>
<p>Na początku należy zastanowić się co chcemy uzyskać. Czy chcemy aby podpowiadane były tylko poszczególne wyrazy składające się na frazy, czy może jednak pełne nazwy rozpoczynające się na podane przez użytkownika litery. W zależności od naszych wyborów musimy przygotować odpowiednie pole, na podstawie którego będziemy budować podpowiedzi.</p>
<h3>Podpowiadanie pojedynczych wyrazów składających się na nazwę</h3>
<p>W przypadku podpowiadania pojedynczych wyrazów powinniśmy podpowiadanie oprzeć o pole, które będzie odpowiednio tokenizowane. W naszym przypadku pole <em>name</em> będzie wystarczające. Należy jednak pamiętać, iż jeżeli chcemy korzystać np. ze stemmingu należałoby zdefiniować kolejny typ, który były go pozbawiony, ze względu na to jak taka analiza działa na zawartość pola.</p>
<h3>Podpowiadanie pełnych nazw</h3>
<p>W przypadku podpowiadania pełnych nazw produktów potrzebujemy innej konfiguracji pola na którym oprzemy podpowiadanie &#8211; najlepsze do tego będzie pole nietokenizowane. Nie możemy jednak wykorzystać do tego celu typu <em>string</em> &#8211; ze względu na to. W tym celu definiujemy pole następująco:
</p>
<pre class="brush:xml">&lt;field name="name_auto" type="text_auto" indexed="true" stored="true" multiValued="false" /&gt;</pre>
<p>Typ ten został zdefiniowany w następujący sposób:
</p>
<pre class="brush:xml">&lt;fieldType name="text_auto" class="solr.TextField"&gt;
 &lt;analyzer&gt;
&nbsp; &lt;tokenizer class="solr.KeywordTokenizerFactory"/&gt;
&nbsp; &lt;filter class="solr.LowerCaseFilterFactory"/&gt;
 &lt;/analyzer&gt;
&lt;/fieldType&gt;</pre>
<p>Aby nie było konieczności modyfikacji formatu danych dodajemy dodatkowo odpowiednią definicję kopiowania informacji:
</p>
<pre class="brush:xml">&lt;copyField source="name" dest="name_auto" /&gt;</pre>
<h3>Jak to wykorzystać ?</h3>
<p>Mając już odpowiednio zaindeksowane dane możemy zacząć korzystanie z Solr. Aby skorzystać z tak przygotowanych danych skorzystać wystarczy dość proste zapytanie:
</p>
<pre class="brush:bash">q=*:*&amp;facet=true&amp;facet.field=POLE&amp;facet.mincount=1&amp;facet.prefix=ZAPYTANIE_UŻYTKOWNIKA</pre>
<p>Gdzie:</p>
<ul>
<li><em>POLE</em> &#8211; pole na jakiego podstawie mamy zamiar realizować podpowiadanie. W naszym przypadku&nbsp;<em>name_auto</em>.</li>
<li><em>ZAPYTANIE_UŻYTKOWNIKA</em> &#8211; litery, które wpisał użytkownik.</li>
</ul>
<p>Warto zauważyć parametr <em>rows=0</em> dodany po to, aby widoczny był tylko wynik facetingu. Oczywiście nie jest to konieczność.</p>
<p>Na przykład:
</p>
<pre class="brush:bash">fl=id,name&amp;rows=0&amp;q=*:*&amp;facet=true&amp;facet.field=name_auto&amp;facet.mincount=1&amp;facet.prefix=dys</pre>
<p>Wynik powyższego zapytania mógłby wyglądać następująco:
</p>
<pre class="brush:xml">&lt;response&gt;
 &lt;lst name="responseHeader"&gt;
&nbsp; &lt;int name="status"&gt;0&lt;/int&gt;
&nbsp; &lt;int name="QTime"&gt;0&lt;/int&gt;
 &lt;/lst&gt;
 &lt;result name="response" numFound="4" start="0"/&gt;
&nbsp;&lt;lst name="facet_counts"&gt;
&nbsp; &lt;lst name="facet_queries"/&gt;
&nbsp; &lt;lst name="facet_fields"&gt;
&nbsp;&nbsp; &lt;lst name="name_auto"&gt;
&nbsp;&nbsp;&nbsp; &lt;int name="dysk twardy"&gt;1&lt;/int&gt;
&nbsp;&nbsp;&nbsp; &lt;int name="dysk twardy samsung"&gt;1&lt;/int&gt;
&nbsp;&nbsp;&nbsp; &lt;int name="dysk twardy seagate"&gt;1&lt;/int&gt;
&nbsp;&nbsp;&nbsp; &lt;int name="dysk twardy toshiba"&gt;1&lt;/int&gt;
&nbsp;&nbsp; &lt;/lst&gt;
&nbsp; &lt;/lst&gt;
&nbsp; &lt;lst name="facet_dates"/&gt;&lt;/lst&gt;
&lt;/response&gt;</pre>
<h3>Dodatkowe możliwości</h3>
<p>Warto wspomnieć o dodatkowych możliwościach jakie niesie za sobą ta metoda.</p>
<p>Pierwsza z możliwości to pokazanie użytkownikowi dodatkowych informacji takich jak ilość wyników jaką dostanie użytkownik po wybraniu odpowiedniej podpowiedzi. Jeżeli chcemy pokazywać takie informacje będzie to na pewno ciekawa opcja.</p>
<p>Możliwość wyboru sortowania wyników facetingu, czyli standardowe wykorzystanie parametru <em>facet.sort</em>. W zależności od potrzeb możemy posortować wyniki po ilości dokumentów (domyślne zachowanie, wartość parametru ustawiamy na <em>true</em>) lub alfabetycznie (wartość parametru ustawiamy na <em>false</em>).</p>
<p>Możemy ograniczyć podpowiedzi, aby nie były generowane te, które mają mniejszą, niż określona ilość wyników. Aby skorzystać z tej możliwości należy przekazać w parametrze <em>facet.mincount</em> ilość dokumentów od jakiej mają być pokazywane wyniki.</p>
<p>I jak dla mnie największy plus tej metody &#8211; możliwość prostego pobierania podpowiedzi tylko tych, które pasują do zapytania użytkownika oraz dodatkowych parametrów, takich jak np. kategoria w której się znajduje. Na przykład chcemy pokazać podpowiedzi dla użytkownika, który znajduje się w dziale AGD naszego sklepu. Podejrzewamy, że w tej chwili nie będą go interesować produkty typu odtwarzacze DVD i dlatego dodajemy parametr <em>fq=dział:agd</em> (zakładając, że mamy taki dział). Po tak zmodyfikowanym zapytaniu, użytkownik nie dostanie podpowiedzi wygenerowanych z całego indeksu, a zawężone, do tego jaki dział przegląda.</p>
<h3>Kilka słów na zakończenie</h3>
<p>Jak wiele metod i ta ma swoje plusy i minusy. Plusem tego rozwiązania jest łatwość jego wykorzystania, brak dodatkowych komponentów oraz to, że wyniki podpowiedzi można w bardzo prosty sposób zawężać, aby były generowane tylko z tych dokumentów, które pasują do zapytania wpisanego przez użytkownika. Jako duży plus można zaliczyć pokazywanie ilości dokumentów, jakie dostanie użytkownik wybierając daną podpowiedź (oczywiście przy zachowaniu takich samych parametrów wyszukiwania). Do minusów należy na pewno konieczność posiadania dodatkowych typów i pól obsługujących podpowiedzi, wbrew pozorom dość ograniczone możliwości oraz obciążenie Solr powodowane przez mechanizm facetingu.</p>
<p>W następnym wpisie dotyczącym funkcjonalności <em>autocomplete</em> postaram się rozszerzyć temat i pokazać kolejne metody generowania podpowiedzi za pomocą Solr.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://solr.pl/2010/10/18/solr-i-autocomplete-cz-1/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Możliwość facetingu w Solr</title>
		<link>https://solr.pl/2010/08/23/mozliwosc-facetingu-w-solr/</link>
					<comments>https://solr.pl/2010/08/23/mozliwosc-facetingu-w-solr/#respond</comments>
		
		<dc:creator><![CDATA[Rafał Kuć]]></dc:creator>
		<pubDate>Mon, 23 Aug 2010 05:48:10 +0000</pubDate>
				<category><![CDATA[Solr]]></category>
		<category><![CDATA[date faceting]]></category>
		<category><![CDATA[facet]]></category>
		<category><![CDATA[facet method]]></category>
		<category><![CDATA[facet parameter]]></category>
		<category><![CDATA[facet query]]></category>
		<category><![CDATA[faceting]]></category>
		<category><![CDATA[local]]></category>
		<category><![CDATA[local params]]></category>
		<category><![CDATA[params]]></category>
		<category><![CDATA[query]]></category>
		<category><![CDATA[range faceting]]></category>
		<category><![CDATA[solr]]></category>
		<guid isPermaLink="false">http://sematext.solr.pl/?p=26</guid>

					<description><![CDATA[Faceting to jedna z metod kategoryzacji treści znalezionych w procesie wyszukiwania informacji. W przypadku Solr jest to podział zbioru znalezionych dokumentów na podstawie pewnego kryterium: zawartości pojedynczego pola, zapytania, czy też na podstawie przedziałów lub dat. W dzisiejszym wpisie postaram]]></description>
										<content:encoded><![CDATA[<p>Faceting to jedna z metod kategoryzacji treści znalezionych w procesie  wyszukiwania informacji. W przypadku Solr jest to podział zbioru  znalezionych dokumentów na podstawie pewnego kryterium: zawartości  pojedynczego pola, zapytania, czy też na podstawie przedziałów lub dat. W  dzisiejszym wpisie postaram się przybliżyć możliwości wykorzystania  mechanizmu facetingu, zarówno tego dostępnego obecnie w Solr 1.4.1, jak  również tego co będzie dostępne w przyszłości.</p>
<p><span id="more-26"></span></p>
<p>Jednym z niewielu źródeł dotyczących facetingu jest wiki Solr, a dokładniej strona pod adresem: <a href="http://wiki.apache.org/solr/SimpleFacetParameters" target="_blank" rel="noopener noreferrer">http://wiki.apache.org/solr/SimpleFacetParameters</a>. Poniższy artykuł jest rozszerzeniem informacji dostępnych na wymienionej stronie.</p>
<p>Faceting w Solr można podzielić na cztery podstawowe rodzaje:</p>
<ul>
<li>faceting po polu,</li>
<li>faceting za pomocą zapytania,</li>
<li>faceting po datach,</li>
<li>faceting po przedziałach.</li>
</ul>
<p>Aby uruchomić mechanizm facetingu, należy do zapytania, które zadajemy do Solr dołączyć parametr <em>facet</em> z wartością <em>true</em>.</p>
<h3>Faceting po polu</h3>
<p>Pierwszy rodzaj facetingu, polegający na kategoryzacji znalezionych  dokumentów ze względu na zawartość podanego pola. Dzięki temu rodzajowi  facetingu jesteśmy w stanie pobrać ilości dokumentów znalezionych na  przykład w poszczególnych kategoriach, czy w podziale na lokalizację  geograficzną. Faceting ten charakteryzuje się sporą liczbą opcji i  możliwości konfigurowania jego zachowań. Poniżej parametry możliwe do  wykorzystania:</p>
<ul>
<li><em>facet.field</em> &#8211; pole po którym będzie wykonywany  faceting. W jednym zapytaniu może być wiele pól po którym wykonywany  będzie faceting. Należy jednak liczyć się ze spadkiem wydajności w  przypadku dużej ilości pól, po których wykonujemy faceting.</li>
<li><em>facet.prefix</em> &#8211; ogranicza wyniki facetingu do tych, które zaczynają się od podanego  przedrostka. Parametr może być definiowany dla poszczególnych pól  przekazanych w parametrze <em>facet.field</em> poprzez dodanie nazwy pola w następujący sposób: <em>facet.NAZWA_POLA.prefix</em>.&nbsp; Z pomocą tego parametru w dość prosty sposób można wdrożyć mechanizm autocomplete.</li>
<li><em>facet.sort</em> &#8211; określa w jaki sposób mają być sortowane wyniki facetingu. Jeżeli  korzystamy z Solr w wersji niższej, niż 1.4 parametr ten przyjmuje  wartości <em>true</em> lub <em>false</em> oznaczające kolejno:  sortowanie po ilości wyników oraz sortowanie według porządku w indeksie  (w przypadku znaków ASCII oznacza sortowania alfabetyczne). Jeżeli  natomiast korzystamy z Solr w wersji 1.4 lub wyższej powinniśmy  korzystać z wartości <em>count</em> (oznaczającej to samo co wartość <em>true</em>) oraz <em>index</em> (oznaczającej to samo co <em>false</em>). Warto wiedzieć, iż wartością domyślną parametru jest wartość <em>true/count</em> w przypadku ustawienia parametru <em>facet.limit</em> na wartość 0 lub <em>false/index</em> w przypadku ustawienia większego limitu. Parametr może być definiowany dla poszczególnych pól przekazanych w parametrze <em>facet.field.</em></li>
<li><em>facet.limit </em>&#8211;  parametr określający jak dużo unikalnych wartości ma zwrócić mechanizm  facetingu dla danego pola. Wartość ujemna tego parametru oznacza brak  ustawionego limitu. Należy pamiętać, iż im większy limit, tym większą  ilość pamięci potrzebujemy oraz tym dłuższy czas wykonywania zapytania.  Wartość domyślna parametru to 100. Parametr może być definiowany dla  poszczególnych pól przekazanych w parametrze <em>facet.field</em>.</li>
<li><em>facet.offset</em> &#8211; parametr określający od którego wyniku facetingu prezentować wyniki.  Wartość domyślna parametru to 0. Parametr może być wykorzystany do  stronicowania wyników facetingu. Parametr może być definiowany dla  poszczególnych pól przekazanych w parametrze <em>facet.field.</em></li>
<li><em>facet.mincount</em> &#8211; parametr określający, jaką minimalną liczność musi mieć dany wynik,  aby pokazany został w wynikach facetingu. Domyślna wartość tego  parametru to 0. Parametr może być definiowany dla poszczególnych pól  przekazanych w parametrze <em>facet.field.</em></li>
<li><em>facet.missing</em> &#8211; parametr określający, czy oprócz standardowych wyników facetingu ma  być dodany wpis o ilości dokumentów nie posiadających wpisu w danym  polu. Parametr przyjmuje wartości <em>true </em>oraz <em>false</em> (wartość domyślna). Parametr może być definiowany dla poszczególnych pól przekazanych w parametrze <em>facet.field.</em></li>
<li><em>facet.method</em> &#8211; parametr wprowadzony w Solr 1.4, przyjmuje wartości <em>enum</em> oraz <em>fc</em>. Określa metodę wyliczania wartości facetingu. Ustawienie metody kryjącej się pod parametrem <em>enum </em>skutkuje  wyliczeniem wszystkich termów w danym polu i wyliczeniem na tej  podstawie wyników facetingu. Ta metoda wyliczenia okazuje się wydajna  przy polach, które mają małą ilość unikalnych termów. Druga metoda  oznaczona jako <em>fc</em> jest standardową metodą wyliczania facetingu  dla pól jednowartościowych i polega na iterowaniu po wszystkich  znalezionych dokumentach w celu wyliczenia wyników facetingu. Parametr  może być definiowany dla poszczególnych pól przekazanych w parametrze <em>facet.field. </em>Domyślną wartością parametru jest <em>fc</em> dla wszystkich pól nie opartych o typ <em>Boolean</em>. <em><br />
</em></li>
<li><em>facet.enum.cache.minDf </em>&#8211;  parametr o dziwnie brzmiącej nazwie określający minimalną liczbę  dokumentów pasujących do pojedynczego termu, aby dla tego termu użyć  metody <em>fc</em> do wyliczania wyników facetingu. Wiem, że to brzmi pokrętnie, ale nie wiem czy da się prościej to wytłumaczyć <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></li>
</ul>
<p>Tak wyglądają parametry facetingu, z jakich możemy skorzystać w  przypadku pierwszego rodzaju facetingu. W większości parametrów  napisałem, iż możliwe jest definiowanie parametru dla poszczególnych  pól. Jak to wygląda ? Załóżmy, że zadajemy następujące zapytanie do  Solr:
</p>
<pre class="brush:xml">q=solr&amp;facet=true&amp;facet.field=category&amp;facet.field=location</pre>
<p>Proste zapytanie o term 'solr&#8217; z włączonym mechanizmem facetingu po dwóch polach &#8211; polu <em>category</em> oraz polu <em>location</em>. Chcielibyśmy, dla pola <em>category</em> pokazać 200 wyników facetingu posortowanych według liczności, a dla pola <em>location</em> pokazać 50 wyników facetingu posortowanych alfabetycznie. Aby to  osiągnąć dodajemy do naszego zapytania następujący fragment:
</p>
<pre class="brush:xml">facet.category.limit=200&amp;facet.category.sort=count&amp;facet.location.limit=50&amp;facet.location.sort=index</pre>
<p>W pokazany sposób możemy bez problemu modyfikować zachowanie mechanizmu  facetingu dla poszczególnych pól dla których jest on wyliczany w ramach  zapytania.</p>
<h3>Faceting za pomocą zapytania</h3>
<p>Metoda facetingu oparta tak naprawdę o jeden parametr &#8211; <em>facet.query</em> do którego podajemy zapytanie. Zapytanie musi być zapisane tak, aby  standardowy parser Lucene był w stanie je zrozumieć. Przykładem  wykorzystania tego parametru jest np. zapytanie o grupę cenową, które  mogłoby wyglądać na przykład tak:
</p>
<pre class="brush:xml">facet.query=price:[0+TO+100]</pre>
<p>Należy  jednak pamiętać, iż każdy dodany do zapytania parametr <em>facet.query</em> to kolejne zapytanie do Lucene, co oznacza spadek wydajności całego zapytania zadawanego do Solr.</p>
<p>W przypadku tej metody facetingu warto wspomnieć, iż istnieje  możliwość zdefiniowania własnego parsera, który ma być użyty do  przetworzenia zapytania przekazanego za pomocą parametru <em>facet.query</em>. Aby skorzystać na przykład z parsera o nazwie <em>myParser</em> przekazany parametr powinien wyglądać następująco:
</p>
<pre class="brush:xml">facet.query={!myParser}aaa.</pre>
<h3>Faceting po datach</h3>
<p>W wersji 1.3 Solr pojawiła się nowa funkcjonalność &#8211; faceting po  datach. Pozwala na wyliczanie wyników facetingu z uwzględnieniem  wszystkich zawiłości związanych z przetwarzaniem dat. Należy pamiętać,  iż faceting po datach może być tylko wykorzystywany z polami opartymi o  typ <em>solr.DateField</em>. Przejdźmy więc do opisania parametrów związanych z facetingiem po datach:</p>
<ul>
<li><em>facet.date </em>&#8211; podobnie jak parametr <em>facet.field</em> parametr ten służy do określenia pól, w których ma być przeprowadzany faceting po datach. Podobnie jak w przypadku parametru <em>facet.field</em> możliwe jest podanie tego parametru wielokrotnie, aby umożliwić faceting po datach na wielu polach w ramach jednego zapytania.</li>
<li><em>facet.date.start </em>&#8211;  parametr określający dolną granicę daty, czyli od której daty ma być  rozpoczęte wyliczanie facetingu. Parametr może być definiowany dla  poszczególnych pól przekazanych w parametrze <em>facet.date</em>. Parametr ten jest wymagany w przypadku korzystania z parametru <em>facet.date</em>.</li>
<li><em>facet.date.end</em> &#8211; parametr określający górną granicę daty, czyli do której daty ma być  zakończone wyliczanie facetingu. Parametr może być definiowany dla  poszczególnych pól przekazanych w parametrze <em>facet.date</em>. Parametr ten jest wymagany w przypadku korzystania z parametru <em>facet.date</em>.</li>
<li><em>facet.date.gap </em>&#8211;  parametr określający przedziały dat, jakie mają być generowane dla  zdefiniowanych granic. Parametr może być definiowany dla poszczególnych  pól przekazanych w parametrze <em>facet.date</em>. Parametr ten jest wymagany w przypadku korzystania z parametru <em>facet.date</em>.</li>
<li><em>facet.date.hardend</em> &#8211; parametr przyjmujący wartości <em>true</em> oraz <em>false</em>, określający co Solr ma zrobić w przypadku kiedy parametr <em>facet.date.gap</em> nie podzieli równo przedziałów pomiędzy zdefiniowanym początkiem, a końcem. Jeżeli ustawimy ten parametr na wartość <em>true</em> ostatni przedział może być większy od podanego w parametrze <em>facet.date.end</em> końca. W przypadku ustawienia na wartość <em>false</em> (która jest wartością domyślną) ostatni przedział dat może być mniejszy  od pozostałych. Parametr może być definiowany dla poszczególnych pól  przekazanych w parametrze <em>facet.date</em>.</li>
<li><em>facet.date.other</em> &#8211; parametr określający jakie wartości oprócz tych wyliczonych dla  określonych przedziałów mają być zawarte w wynikach facetingu. Parametr  może być definiowany dla poszczególnych pól przekazanych w parametrze <em>facet.date</em>. Parametr może przyjmować następujące wartości:
<ul>
<li><em>before</em> &#8211; oprócz przedziałów wyniki facetingu będą  zawierać wyliczenia ilości dla dat mieszczących się przed granicą  zdefiniowaną w parametrze <em>facet.date.start,</em></li>
<li><em>after </em>&#8211;  oprócz przedziałów wyniki facetingu będą zawierać wyliczenia ilości dla  dat mieszczących się za granicą zdefiniowaną w parametrze <em>facet.date.end,</em></li>
<li><em>between</em> &#8211; do wyników facetingu po datach zostanie dołączona informacja o licznościach w przedziale zdefiniowanym przez parametry <em>facet.date.start</em> oraz <em>facet.date.end,</em></li>
<li><em>all </em>&#8211; skrót określający, że dla danego pola mają zostać dodane trzy powyższe opcje,</li>
<li><em>none &#8211;</em> wartość określająca, iż żadna dodatkowa informacja ma nie być dołączona do wyników facetingu.</li>
</ul>
</li>
<li><em>facet.date.include</em> &#8211; parametr, który zostanie  wprowadzony w Solr 4.0. Parametr pozwala na domykanie, bądź otwieranie  przedziałów zdefiniowanych przy pomocy parametrów <em>facet.date.start</em> oraz <em>facet.date.end</em>. Parametr będzie przyjmował następujące wartości:
<ul>
<li><em>lower </em>&#8211; każdy z powstałych przedziałów będzie zawierał swoją dolną granicę,</li>
<li><em>upper</em> &#8211; każdy z powstałych przedziałów będzie zawierał swoją górną granicę,</li>
<li><em>egde</em> &#8211; pierwszy i ostatni przedział będą zawierały swoje zewnętrzne granice &#8211;  czyli dolną dla pierwszego przedziału i górną dla ostatniego  przedziału,</li>
<li><em>outer</em> &#8211; parametr określający, iż przedziały zdefiniowane przez wartości <em>before</em> i <em>after</em> parametru <em>facet.date.other</em> będą zawierały swoje granice, nawet jeżeli inne przedziały zawierają już te granice,</li>
<li><em>all</em> &#8211; parametr powodujący włączenie czterech powyższych opcji.</li>
</ul>
</li>
</ul>
<p>Tak przedstawiają się opcje facetingu po datach. Poniżej przykład wykorzystania tego rodzaju facetingu:
</p>
<pre class="brush:xml">q=solr&amp;facet=true&amp;facet.date=addDate&amp;facet.date.start=NOW/DAY-30DAYS&amp;facet.date.end=NOW/DAY%2B30DAYS&amp;facet.date.gap=%2B1DAY</pre>
<p>Zajmijmy się facetingiem w tym zapytaniu &#8211; faceting po datach po polu o nazwie <em>addDate</em>.  Jako dolną granicę ustawiamy datę o 30 dni wcześniejszą niż obecna,  górna granica to data o 30 dni później, niż w chwili zadawania  zapytania. Przedziały mają być wielkości jednego dnia.</p>
<h3>Faceting po przedziałach</h3>
<p>Funkcjonalność która dostępna będzie w Solr 3.1. Jeżeli ktoś chce już  teraz ją testować, to zarówno trunk, jak i branch 3.x mają tą  funkcjonalność zaimplementowaną. Ta metoda facetingu powstała jako  rozszerzenie pomysłu facetingu po datach. Funkcjonalność działa  analogicznie do facetingu po datach, czyli w wyniku działania dostajemy  listę przedziałów skonstruowanych automatycznie na podstawie parametrów.  Lista parametrów, jakie charakteryzują działanie mechanizmu:</p>
<ul>
<li><em>facet.range </em>&#8211; parametr określający po jakich polach ma  być przeprowadzony faceting po przedziałach. Parametr może być  przekazywany wielokrotnie.</li>
<li><em>facet.range.start </em>&#8211;  parametr określający dolną granicę przedziałów, czyli wartość od której  ma być  rozpoczęte wyliczanie facetingu. Parametr może być definiowany  dla  poszczególnych pól przekazanych w parametrze <em>facet.range</em>. Parametr ten jest wymagany w przypadku korzystania z parametru <em>facet.range</em>.</li>
<li><em>facet.range.end</em> &#8211; parametr określający dolną granicę przedziałów, czyli wartość na  której ma być skończone wyliczanie facetingu. Parametr może być  definiowany  dla  poszczególnych pól przekazanych w parametrze <em>facet.range</em>. Parametr ten jest wymagany w przypadku korzystania z parametru <em>facet.range</em>.</li>
<li><em>facet.range.gap</em> &#8211; parametr określający wielkość przedziałów, jakie mają być generowane  dla  zdefiniowanych granic. Parametr może być definiowany dla  poszczególnych  pól przekazanych w parametrze <em>facet.range</em>. Parametr ten jest wymagany w przypadku korzystania z parametru <em>facet.range</em>.</li>
<li><em>facet.range.hardend</em> &#8211; parametr przyjmujący wartości <em>true</em> oraz <em>false</em>, określający co Solr ma zrobić w przypadku kiedy parametr <em>facet.range.gap</em> nie podzieli równo przedziałów pomiędzy zdefiniowanym początkiem, a końcem. Jeżeli ustawimy ten parametr na wartość <em>true</em> ostatni przedział może być większy od podanego w parametrze <em>facet.range.end</em> końca. W przypadku ustawienia na wartość <em>false</em> (która jest wartością domyślną) ostatni przedział może być mniejszy  od  pozostałych. Parametr może być definiowany dla poszczególnych pól   przekazanych w parametrze <em>facet.range</em>.</li>
<li><em>facet.range.other</em> &#8211; parametr określający jakie wartości oprócz tych wyliczonych dla   określonych przedziałów mają być zawarte w wynikach facetingu. Parametr   może być definiowany dla poszczególnych pól przekazanych w parametrze <em>facet.range</em>. Parametr może przyjmować następujące wartości:
<ul>
<li><em>before</em> &#8211; oprócz przedziałów wyniki facetingu będą  zawierać wyliczenia ilości dla przedziału mieszczących się przed granicą  zdefiniowaną w parametrze <em>facet.range.start,</em></li>
</ul>
<ul>
<li><em>after </em>&#8211; oprócz przedziałów wyniki facetingu będą  zawierać  wyliczenia ilości dla przedziału mieszczących się za granicą  zdefiniowaną w  parametrze <em>facet.range.end,</em></li>
</ul>
<ul>
<li><em>between</em> &#8211; do wyników facetingu po rozdziałach zostanie dołączona informacja o licznościach w przedziale zdefiniowanym przez parametry <em>facet.range.start</em> oraz <em>facet.range.end,</em></li>
</ul>
<ul>
<li><em>all </em>&#8211; skrót określający, że dla danego pola mają zostać dodane trzy powyższe opcje,</li>
<li><em>none &#8211;</em> wartość określająca, iż żadna dodatkowa informacja ma nie być dołączona do wyników facetingu po przedziałach.</li>
</ul>
</li>
<li><em>facet.range.include </em>&#8211; parametr pozwala na  domykanie, bądź otwieranie przedziałów zdefiniowanych przy pomocy  parametrów <em>facet.range.start</em> oraz <em>facet.range.end</em>. Parametr przyjmuje następujące wartości:
<ul>
<li><em>lower </em>&#8211; każdy z powstałych przedziałów będzie zawierał swoją dolną granicę,</li>
<li><em>upper</em> &#8211; każdy z powstałych przedziałów będzie zawierał swoją górną granicę,</li>
<li><em>egde</em> &#8211; pierwszy i ostatni przedział będą zawierały swoje  zewnętrzne granice  &#8211; czyli dolną dla pierwszego przedziału i górną dla  ostatniego  przedziału,</li>
<li><em>outer</em> &#8211; parametr określający, iż przedziały zdefiniowane przez wartości <em>before</em> i <em>after</em> parametru <em>facet.date.other</em> będą zawierały swoje granice, nawet jeżeli inne przedziały zawierają już te granice,</li>
<li><em>all</em> &#8211; parametr powodujący włączenie czterech powyższych opcji.</li>
</ul>
</li>
</ul>
<p>Jak widać parametry facetingu po przedziałach są prawie identyczne,  jak w przypadku facetingu po datach. Działanie jest także analogiczne.  Przykładem zapytania z wykorzystaniem facetingu po datach może być  następujące zapytanie:
</p>
<pre class="brush:xml">q=solr&amp;facet=true&amp;facet.range=price&amp;facet.range.start=0&amp;facet.range.end=1000&amp;facet.range.gap=100</pre>
<p>Tak przeszliśmy przez wszystkie rodzaje facetingu. Jednak to jeszcze  nie wszystko. Użytkownicy Solr w wersji 1.4 i wyższych mają możliwość  korzystania z tzw. <em>LocalParams</em> wraz z facetingiem.</p>
<h3>LocalParams i faceting</h3>
<p>Załóżmy takie wymaganie. Mamy zapytanie, które zwraca wyniki wyszukiwania dla słowa <em>solr</em> oraz, które ma zdefiniowane dwa filtry jeden dla kategorii, a drugi dla  kraju z którego pochodzi dokument. Oprócz wyników wyszukiwania chcemy  umożliwić, w ramach wyników wyszukiwania, nawigację po regionach oraz po  kategoriach, ale chcielibyśmy, aby liczności nie były od siebie  zależne. To znaczy chcielibyśmy dać możliwość nawigacji po regionach dla  słowa <em>solr</em>, ale nie zawężonych do wybranej kategorii, oraz po  kategorii, ale nie zawężonej do wybranego regionu. Żeby zrobić to w Solr  w wersji 1.3 lub wcześniejszej, należałoby napisać następujące  zapytania:
</p>
<pre class="brush:xml">q=solr&amp;fq=category:search&amp;fq=region:poland
q=solr&amp;facet=true&amp;facet.field=category&amp;facet.field=region</pre>
<p>Dwa zapytania dlatego, że po pierwsze musimy pobrać zawężone wyniki  wyszukiwania, a z drugiej strony potrzebujemy niezawężonych wyników  wyszukiwania po to, aby pobrać wymagane liczności za pomocą facetingu.</p>
<p>W przypadku Solr w wersji 1.4 lub wyższej mamy możliwość skrócenia  tego do jednego zapytania. Do tego celu wykorzystamy możliwość tagowania  i wykluczania tagowanych parametrów. Pierwsze zapytanie zmieniamy w  następujący sposób:
</p>
<pre class="brush:xml">q=solr&amp;fq={!tag=categoryFQ}fq=category:search&amp;fq={!tag=regionFQ}region:poland</pre>
<p>Na razie wyniki wyszukiwania się nie zmienią. Do powyższego zapytania  zostały dodane tagi nadające nazwę każdemu z wykorzystywanych filtrów  po to, abyśmy mogli wykluczyć je w facetingu.</p>
<p>Drugie zapytanie modyfikujemy w następujący sposób:
</p>
<pre class="brush:xml">q=solr&amp;facet=true&amp;facet.field={!ex=categoryFQ,regionFQ}category&amp;facet.field={!ex=categoryFQ,regionFQ}region</pre>
<p>Tutaj także na razie wyniki facetingu nie uległy zmianie. Dodaliśmy  do facetingu wykluczenia, które mówią o tym, że filtry o nazwach <em>categoryFQ</em> oraz <em>regionFQ</em> mają nie być brane pod uwagę przy wyliczaniu wyników facetingu.</p>
<p>Tak zmodyfikowane zapytanie łączymy w jedno, które powinno wyglądać następująco:
</p>
<pre class="brush:xml">q=solr&amp;fq={!tag=categoryFQ}fq=category:search&amp;fq={!tag=regionFQ}region:poland&amp;facet=true&amp;facet.field={!ex=categoryFQ,regionFQ}category&amp;facet.field={!ex=categoryFQ,regionFQ}region</pre>
<p>Więcej o <em>LocalParams</em> napiszę w jednym z kolejnych wpisów.</p>
<h3>Kilka słów na koniec</h3>
<p>Mam nadzieję, że tym artykułem przybliżyłem możliwości wykorzystania  facetingu w Solr, zarówno w starszych wersjach, w tej obecnej, jak i  tych, które pojawią się w przyszłości.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://solr.pl/2010/08/23/mozliwosc-facetingu-w-solr/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Proces wyszukiwania</title>
		<link>https://solr.pl/2010/08/09/proces-wyszukiwania/</link>
					<comments>https://solr.pl/2010/08/09/proces-wyszukiwania/#respond</comments>
		
		<dc:creator><![CDATA[Marek Rogoziński]]></dc:creator>
		<pubDate>Mon, 09 Aug 2010 16:12:16 +0000</pubDate>
				<category><![CDATA[Ogólna]]></category>
		<category><![CDATA[faceting]]></category>
		<category><![CDATA[filtrowanie]]></category>
		<category><![CDATA[podstawy]]></category>
		<category><![CDATA[sortowanie]]></category>
		<category><![CDATA[wyszukiwanie]]></category>
		<guid isPermaLink="false">http://sematext.solr.pl/?p=20</guid>

					<description><![CDATA[Niniejszym inaugurujemy część solr.pl poświęconą tym zagadnieniom, które nie są związane z konkretnym silnikiem wyszukiwania a raczej z budową i rozwojem funkcjonalności serwisów internetowych związanych z wyszukiwaniem. Czy zastanawialiście się co powoduje, że wyszukiwarka w serwisie jest uważana za dobrą?]]></description>
										<content:encoded><![CDATA[<p>Niniejszym inaugurujemy część solr.pl poświęconą tym zagadnieniom, które nie są związane z konkretnym silnikiem wyszukiwania a raczej z budową i rozwojem funkcjonalności serwisów internetowych związanych z wyszukiwaniem.</p>
<p>Czy zastanawialiście się co powoduje, że wyszukiwarka w serwisie jest uważana za dobrą? By odpowiedzieć na to pytanie, należy się zastanowić, jak wygląda typowy proces znajdowania przez klienta pożądanej przez niego informacji. I czy jest coś takiego, jak typowy proces.</p>
<p><span id="more-20"></span></p>
<p>W projektach, w których udało mi się uczestniczyć dobrze sprawdzał się model mówiący o podziale na następujące fazy:</p>
<ul>
<li>wyszukiwanie</li>
<li>redefinicja zapytania</li>
<li>filtracja</li>
<li>sortowanie</li>
<li>przeglądanie wyników</li>
</ul>
<p>Nie wszystkie te fazy muszą wystąpić, ich kolejność czasem będzie inna, czasem też poszczególne fazy będą występować wielokrotnie. Również w zależności od produktu, posiadanych danych i ich ilości nie wszystkie z nich system musi udostępniać.</p>
<p><strong>1. Wyszukiwanie</strong></p>
<p><strong><img decoding="async" class="alignleft size-medium wp-image-212" style="margin: 10px" src="http://solr.pl/wp-content/uploads/2010/08/wyszukiwanie-300x124.png" alt="" width="300" height="124"></strong>Tu użytkownik może wykazać się największą inwencją wpisując w pole (albo wiele pól) frazę wyszukiwania. I jest to jednocześnie krytyczny moment, w którym często nowy użytkownik podejmuje decyzję: zostać czy znaleźć inny, lepszy serwis. Na co zwykle zwracamy uwagę:</p>
<ul>
<li>czytelność wyników i sensowność 	doboru wyświetlanych informacji – celem użytkownika jest 	znalezienie konkretnego elementu lub grupy elementów spełniających 	kryteria (często mętne i niekonkretne) wyszukiwania. Dlatego musi 	mieć możliwość wstępnego odrzucenia tych elementów, które mu 	z jakiś powodów nie pasują. Błędem jest brak podstawowych dla 	użytkownika informacji (np. serwis z ogłoszeniami sprzedaży 	mieszkań, który nie pokazuje na liście wyników metrażu ani 	lokalizacji! )</li>
<li>liczba znalezionych wyników – 	jeśli wyników jest mało, może to np. sugerować ograniczony 	asortyment w sklepie</li>
<li>przystawanie wyników do frazy 	wyszukiwania – jeśli w sklepie komputerowym na hasło: „notebook” 	na pierwsza strona zawiera tylko pokrowce na notebooki, może to 	sugerować, że firma sprzedaje tylko akcesoria</li>
<li>możliwości nawigacji i łatwość 	dokonania wyboru – jeśli wyników wyszukiwania jest dużo,  	zostawienie użytkownikowi możliwości tylko zmiany zapytania albo 	męczącego przebijania  się przez strony wyników nie jest dobrym 	pomysłem.</li>
</ul>
<p><strong>2. Redefinicja zapytania</strong></p>
<p>W zależności od uzyskanych wyników wyszukiwania, zwykle od pierwszego wrażenia jakości tych wyników, użytkownik może zdecydować się powtórzyć wyszukiwanie. Im więcej faz redefinicji, tym gorsze wrażenie klienta i większa szansa na opuszczenie sklepu. Zwłaszcza, jeśli użytkownik, w jego mniemaniu wpisał bardzo ogólną frazę, a nie dostał żadnych wyników.</p>
<p><strong>3. Filtracja</strong></p>
<p><img decoding="async" class="alignleft size-medium wp-image-210" style="margin: 15px" src="http://solr.pl/wp-content/uploads/2010/08/filtrowanie-185x300.png" alt="" width="185" height="300">Rodzaj zwróconych wyników jest w porządku, pytanie, jak teraz użytkownik może ograniczyć ich liczbę do tych, które są szczególnie interesujące (czyli odrzucić te mniej ciekawe). W tym celu umożliwia się dalsze nawigowanie po wynikach wyszukiwania w oparciu o filtry. Tutaj zwykle zwracamy uwagę na:</p>
<ul>
<li>łatwość dodawania i usuwania 	filtru – zakładając, że użytkownik ma jedynie ogólne pojęcie 	czego szuka, należy się spodziewać, że będzie on wielokrotnie 	zmieniał kryteria wyszukiwania – niedopuszczalne są ścieżki 	nawigacji, gdzie jedyną metodą powrotu do wcześniej 	odfiltrowanych elementów jest przycisk „powrót” w 	przeglądarce, lub rozpoczęcie kolejnego wyszukiwania.</li>
<li>zależność filtrów od rodzaju 	wyszukiwania – szukając nowego komputera interesujący jest inny 	zestaw parametrów niż wybierając książkę. Chociaż brzmi to 	jak oczywistość, zbyt często można spotkać sytuacje, gdzie 	zmiana asortymentu sklepu nie pociąga za sobą zmian definicji 	filtrów, lub zestaw filtrów jest narzucony „z góry”. W 	efekcie pojawiają się opcje typu „kolor opon”.</li>
<li>podanie liczb określających 	liczbę wyników po zastosowaniu filtra – niedoceniana 	funkcjonalność, jednak pozwala na wybieranie przez użytkownika 	optymalnego sposobu filtrowania: jeśli koniecznie w notebooku muszę 	mieć wbudowaną kamerę, to filtr „Z wbudowaną kamerą (3)” od 	razu sugeruje, że wybór koloru będzie mniej ważny i nie ma sobie 	co nim zawracać głowy.</li>
</ul>
<p><strong>4. Sortowanie<br />
</strong></p>
<p><img loading="lazy" decoding="async" class="alignleft size-full wp-image-211" style="margin: 15px" src="http://solr.pl/wp-content/uploads/2010/08/sortowanie.png" alt="" width="194" height="35">Pozwala się zająć klientowi przeglądaniem wyników w najwygodniejszej kolejności (np. od najtańszych produktów). W praktyce liczba opcji jest mocno ograniczona, np. Pomysł sortowania po cechach produktu może konfliktować z filtrowaniem.</p>
<p><strong>5. Przeglądanie Wyników</strong></p>
<p>Tutaj użytkownik już zapoznaje się z wybranymi produktami. Z punktu widzenia wyszukiwania to już dość nudny temat <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;" /> Warto jednak pamiętać o wygodnym powrocie do listy wyników: tu błędem jest np. automatyczny powrót na pierwszą stronę wyników, albo zmuszanie użytkownika do  przewijania strony w poszukiwaniu ostatnio oglądanego elementu.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://solr.pl/2010/08/09/proces-wyszukiwania/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
