<?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>query &#8211; Solr.pl</title>
	<atom:link href="https://solr.pl/tag/query/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>Thu, 12 Nov 2020 11:13:00 +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>Switch query parser &#8211; szybkie spojrzenie</title>
		<link>https://solr.pl/2013/06/03/switch-query-parser-szybkie-spojrzenie/</link>
					<comments>https://solr.pl/2013/06/03/switch-query-parser-szybkie-spojrzenie/#respond</comments>
		
		<dc:creator><![CDATA[Rafał Kuć]]></dc:creator>
		<pubDate>Mon, 03 Jun 2013 10:12:33 +0000</pubDate>
				<category><![CDATA[Solr]]></category>
		<category><![CDATA[parser]]></category>
		<category><![CDATA[query]]></category>
		<category><![CDATA[query praser]]></category>
		<category><![CDATA[solr]]></category>
		<category><![CDATA[switch]]></category>
		<guid isPermaLink="false">http://sematext.solr.pl/?p=513</guid>

					<description><![CDATA[Ilość dostępnych query parserów w Solr zawsze mnie zadziwiała. Czy jest tu ktoś kto jest w stanie wymienić je wszystkie? Jednak w dzisiejszym wpisie nie będziemy się przyglądać wszystkim parserom, ale jednemu konkretnemu o nazwie SwitchQueryParser wprowadzonemu w Solr 4.2.]]></description>
										<content:encoded><![CDATA[<p>Ilość dostępnych query parserów w Solr zawsze mnie zadziwiała. Czy jest tu ktoś kto jest w stanie wymienić je wszystkie? Jednak w dzisiejszym wpisie nie będziemy się przyglądać wszystkim parserom, ale jednemu konkretnemu o nazwie <em>SwitchQueryParser</em> wprowadzonemu w Solr 4.2.</p>
<p><span id="more-513"></span></p>
<h3>Idea działania</h3>
<p>Idea działania jest dość prosta &#8211; umożliwić przetwarzanie prostego warunku po stronie Solr i przekazanie do jako podzapytanie. Na przykład, wyobraźmy sobie, że mamy aplikację, która rozumie cztery wartości pola <em>priceRange</em>:</p>
<ul>
<li><em>cheap</em> &#8211; w przypadku kiedy cena produktu, zapisana w polu <em>price</em>, jest niższa, niż 10$,</li>
<li><em>average</em> &#8211; w przypadku kiedy cena produktu jest pomiędzy 10, a 30$,</li>
<li><em>expensive</em> &#8211; w przypadku kiedy cena produktu jest wyższa niż 30$,</li>
<li><em>all</em> &#8211; w przypadku kiedy chcemy pokazać wszystkie produkty, bez względu na cenę</li>
</ul>
<p>Chcielibyśmy tę logikę zaszyć w Solr, aby nie było konieczności zmian po stronie aplikacji za każdym razem kiedy chcemy zmienić powyższe warunki. W tym właśnie celu wykorzystamy <em>SwitchQueryParser</em>.</p>
<h3>Nasze zapytanie</h3>
<p>Załóżmy, że nasza aplikacja jest w stanie zadać następujące zapytanie:
</p>
<pre class="brush:bash">http://localhost:8983/solr/collection1/price?q=*:*&amp;priceRange=cheap</pre>
<p>A zatem chcielibyśmy, aby na powyższe zapytanie Solr zwrócił wszystkie dokumenty (<em>q=*:*</em>), ale zawężone do tych posiadających cenę niższą niż 10$ (parameter <em>priceRange=cheap</em>).</p>
<h3>Konfiguracja Solr</h3>
<p>Oczywiście nie chcemy konfiguracji naszych zakresów pola <em>price</em> wysyłać w zapytaniu, bo nie miałoby to większego sensu. My zdecydowaliśmy się stworzyć nowy SearchHandler o nazwie /<em>price</em> z następującą konfiguracją (dodajemy go do pliku <em>solrconfig.xml</em>):
</p>
<pre class="brush:xml">&lt;requestHandler name="/price"&gt;
 &lt;lst name="defaults"&gt;
  &lt;str name="priceRange"&gt;all&lt;/str&gt;
 &lt;/lst&gt;
 &lt;lst name="appends"&gt;
  &lt;str name="fq"&gt;{!switch case.all='price:[* TO *]' case.cheap='price:[0 TO 10]' case.average='price:[10 TO 30]' case.expensive='price:[30 TO *]' v=$priceRange}&lt;/str&gt;
 &lt;/lst&gt;
&lt;/requestHandler&gt;</pre>
<p>Jak widać konfiguracja naszego SearchHandlera składa się z dwóch elementów. Po pierwsze w sekcji <em>defaults</em> zdefiniowaliśmy, iż parametr <em>priceRange</em> będzie domyślnie przyjmować wartość <em>all</em>. Dodatkowo zdefiniowaliśmy filtr&nbsp;(<em>fq</em>) działający w oparciu o <em>SwitchQueryParser</em> (<em>!switch</em>). Dla każdej z możliwych wartości parametru <em>priceRange</em> (<em>v=$priceRange</em>) zdefiniowaliśmy odpowiedni filtr wykorzystując wyrażenie <em>case.wartośćPolaPriceRange=filtr</em>. Zatem, kiedy wartość parametru <em>priceRange</em> w zapytaniu będzie wynosić <strong><em>cheap</em></strong> to filtr zdefiniowany przez <em>case.<strong>cheap</strong></em> będzie wykorzystany, jeżeli ta wartość będzie wynosić&nbsp;<strong>expensive</strong> to filtr zdefiniowany przez&nbsp;<em>case.<strong>expensive</strong></em> będzie wykorzystany, itd.</p>
<h3>O czym należy pamiętać</h3>
<p>Jest jedna, ważna rzecz o której należy pamiętać w przypadku korzystania z opisywanego parsera. W naszym przypadku podanie do parametru <em>priceRange</em> wartości innej, niż 4 powyżej wymienione będzie skutkowało błędem Solr.</p>
<h3>Kilka słów podsumowania</h3>
<p>Moim skromnym zdaniem <em>SwitchQueryParser</em> pomimo tego, że nie będzie stosowany przez większość użytkowników Solr wydaje się być fajnym pomysłem. Biorąc pod uwagę to, że pozwala ukryć przed aplikacją bardzo prostą logikę oraz to, że jest dość prosty, a co za tym nie wymagający jeżeli chodzi o zasoby, na pewno znajdą się użytkownicy, którym ten parser ułatwi pracę <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/06/03/switch-query-parser-szybkie-spojrzenie/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Do czego może przydać się tie w Dismax&#8217;ie ?</title>
		<link>https://solr.pl/2012/02/06/do-czego-moze-przydac-sie-tie-w-dismaxie/</link>
					<comments>https://solr.pl/2012/02/06/do-czego-moze-przydac-sie-tie-w-dismaxie/#respond</comments>
		
		<dc:creator><![CDATA[Rafał Kuć]]></dc:creator>
		<pubDate>Mon, 06 Feb 2012 22:23:11 +0000</pubDate>
				<category><![CDATA[Solr]]></category>
		<category><![CDATA[dismax]]></category>
		<category><![CDATA[query]]></category>
		<category><![CDATA[solr]]></category>
		<category><![CDATA[tie]]></category>
		<guid isPermaLink="false">http://sematext.solr.pl/?p=398</guid>

					<description><![CDATA[Dismax parser obecny jest w Solr od niepamiętnych czasów. W większości wypadków jednak korzystamy z parameterów takich, jak qf, pf, czy mm&#160;zapominając zupełnie o bardzo przydatnym parametrze pozwalającym kontrolować wpływ mniej ważnych pól na score dokumentu, czyli o parametrze tie.]]></description>
										<content:encoded><![CDATA[<p>Dismax parser obecny jest w Solr od niepamiętnych czasów. W większości wypadków jednak korzystamy z parameterów takich, jak <em>qf</em>, <em>pf</em>, czy <em>mm</em>&nbsp;zapominając zupełnie o bardzo przydatnym parametrze pozwalającym kontrolować wpływ mniej ważnych pól na score dokumentu, czyli o parametrze <em>tie</em>.</p>
<p><span id="more-398"></span></p>
<h3>Tie, czyli co ?</h3>
<p>Parametr <em>tie</em>&nbsp;pozwala kontrolować, jak mocny wpływ na score mają pola, które otrzymały score&nbsp;mniejszy od najwyższego. W przypadku ustawienia parametru <em>tie</em>&nbsp;na wartość 0.0, podczas liczenia score będą brane pod uwagę tylko i wyłącznie te pola, które otrzymały najwyższy score. W przypadku ustawienia tego parametru na wartość 0.99, pola, które mają score mniejszy od najwyższego będą traktowane prawie identycznie, jak pole o najwyższym wyliczonym score. Sprawdźmy zatem, czy jest to prawda.</p>
<h3>Struktura danych i ich przykład</h3>
<p>Do testów wybrałem sobie bardzo prostą strukturę indeksu, która teoretycznie mogłaby przedstawiać produkty w sklepie internetowym, oczywiście w ogromnym uproszczeniu:
</p>
<pre class="brush:xml">&lt;field name="id" type="string" indexed="true" stored="true" required="true" /&gt;
&lt;field name="title" type="text_ws" indexed="true" stored="true" /&gt;
&lt;field name="description" type="text_ws" indexed="true" stored="true" /&gt;
&lt;field name="author" type="text_ws" indexed="true" stored="true" multiValued="true" /&gt;</pre>
<p>Typ <em>text_ws</em>&nbsp;został zdefiniowany w następujący sposób:
</p>
<pre class="brush:xml">&lt;fieldType name="text_ws" class="solr.TextField" positionIncrementGap="100"&gt;
 &lt;analyzer&gt;
  &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
  &lt;filter class="solr.LowerCaseFilterFactory"/&gt;
 &lt;/analyzer&gt;
&lt;/fieldType&gt;</pre>
<p>Natomiast przykładowe dane wyglądają w następujący sposób:
</p>
<pre class="brush:xml">&lt;add&gt;
 &lt;doc&gt;
  &lt;field name="id"&gt;1&lt;/field&gt;
  &lt;field name="title"&gt;First test book&lt;/field&gt;
  &lt;field name="description"&gt;This is a description of the first test book by Joe and Jane Blow&lt;/field&gt;
  &lt;field name="author"&gt;Joe Blow&lt;/field&gt;
  &lt;field name="author"&gt;Jane Blow&lt;/field&gt;
 &lt;/doc&gt;
 &lt;doc&gt;
  &lt;field name="id"&gt;2&lt;/field&gt;
  &lt;field name="title"&gt;Second test book&lt;/field&gt;
  &lt;field name="description"&gt;This is a description of the second test book by Joe Blow&lt;/field&gt;
  &lt;field name="author"&gt;Joe Blow&lt;/field&gt;
 &lt;/doc&gt;
&lt;/add&gt;</pre>
<h3>Rezultat z tie == 0.01</h3>
<p>Zacznijmy więc testy. Na pierwszy ogień idzie następujące zapytanie:
</p>
<pre class="brush:xml">defType=dismax&amp;qf=title^1000 description author^10&amp;tie=0.01&amp;fl=id,score&amp;debugQuery=on&amp;indent=true&amp;q=joe blow book</pre>
<p>Powyższe skutkuje następującymi wynikami zwróconymi przez Solr (wizualizacja &#8211; <a href="http://explain.solr.pl/explains/cf0wnkpj" target="_blank" rel="noopener noreferrer">http://explain.solr.pl/explains/cf0wnkpj</a>):
</p>
<pre class="brush:xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;response&gt;
&lt;lst name="responseHeader"&gt;
  &lt;int name="status"&gt;0&lt;/int&gt;
  &lt;int name="QTime"&gt;8&lt;/int&gt;
  &lt;lst name="params"&gt;
    &lt;str name="fl"&gt;id,score&lt;/str&gt;
    &lt;str name="debugQuery"&gt;on&lt;/str&gt;
    &lt;str name="indent"&gt;true&lt;/str&gt;
    &lt;str name="tie"&gt;0.01&lt;/str&gt;
    &lt;str name="q"&gt;joe blow book&lt;/str&gt;
    &lt;str name="qf"&gt;title^1000 description author^10&lt;/str&gt;
    &lt;str name="defType"&gt;dismax&lt;/str&gt;
  &lt;/lst&gt;
&lt;/lst&gt;
&lt;result name="response" numFound="2" start="0" maxScore="0.07342677"&gt;
  &lt;doc&gt;
    &lt;float name="score"&gt;0.07342677&lt;/float&gt;
    &lt;str name="id"&gt;2&lt;/str&gt;
  &lt;/doc&gt;
  &lt;doc&gt;
    &lt;float name="score"&gt;0.073365316&lt;/float&gt;
    &lt;str name="id"&gt;1&lt;/str&gt;
  &lt;/doc&gt;
&lt;/result&gt;
&lt;lst name="debug"&gt;
  &lt;str name="rawquerystring"&gt;joe blow book&lt;/str&gt;
  &lt;str name="querystring"&gt;joe blow book&lt;/str&gt;
  &lt;str name="parsedquery"&gt;+((DisjunctionMaxQuery((author:joe^10.0 | title:joe^1000.0 | description:joe)~0.01) DisjunctionMaxQuery((author:blow^10.0 | title:blow^1000.0 | description:blow)~0.01) DisjunctionMaxQuery((author:book^10.0 | title:book^1000.0 | description:book)~0.01))~3) ()&lt;/str&gt;
  &lt;str name="parsedquery_toString"&gt;+(((author:joe^10.0 | title:joe^1000.0 | description:joe)~0.01 (author:blow^10.0 | title:blow^1000.0 | description:blow)~0.01 (author:book^10.0 | title:book^1000.0 | description:book)~0.01)~3) ()&lt;/str&gt;
  &lt;lst name="explain"&gt;
    &lt;str name="2"&gt;
0.07342677 = (MATCH) sum of:
  0.07342677 = (MATCH) sum of:
    8.957935E-4 = (MATCH) max plus 0.01 times others of:
      8.9543534E-4 = (MATCH) weight(author:joe^10.0 in 1), product of:
        0.0024097771 = queryWeight(author:joe^10.0), product of:
          10.0 = boost
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0532142E-4 = queryNorm
        0.3715843 = (MATCH) fieldWeight(author:joe in 1), product of:
          1.0 = tf(termFreq(author:joe)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.625 = fieldNorm(field=author, doc=1)
      3.5817415E-5 = (MATCH) weight(description:joe in 1), product of:
        2.4097772E-4 = queryWeight(description:joe), product of:
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0532142E-4 = queryNorm
        0.14863372 = (MATCH) fieldWeight(description:joe in 1), product of:
          1.0 = tf(termFreq(description:joe)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.25 = fieldNorm(field=description, doc=1)
    8.957935E-4 = (MATCH) max plus 0.01 times others of:
      8.9543534E-4 = (MATCH) weight(author:blow^10.0 in 1), product of:
        0.0024097771 = queryWeight(author:blow^10.0), product of:
          10.0 = boost
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0532142E-4 = queryNorm
        0.3715843 = (MATCH) fieldWeight(author:blow in 1), product of:
          1.0 = tf(termFreq(author:blow)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.625 = fieldNorm(field=author, doc=1)
      3.5817415E-5 = (MATCH) weight(description:blow in 1), product of:
        2.4097772E-4 = queryWeight(description:blow), product of:
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0532142E-4 = queryNorm
        0.14863372 = (MATCH) fieldWeight(description:blow in 1), product of:
          1.0 = tf(termFreq(description:blow)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.25 = fieldNorm(field=description, doc=1)
    0.07163518 = (MATCH) max plus 0.01 times others of:
      0.07163482 = (MATCH) weight(title:book^1000.0 in 1), product of:
        0.2409777 = queryWeight(title:book^1000.0), product of:
          1000.0 = boost
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0532142E-4 = queryNorm
        0.29726744 = (MATCH) fieldWeight(title:book in 1), product of:
          1.0 = tf(termFreq(title:book)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.5 = fieldNorm(field=title, doc=1)
      3.5817415E-5 = (MATCH) weight(description:book in 1), product of:
        2.4097772E-4 = queryWeight(description:book), product of:
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0532142E-4 = queryNorm
        0.14863372 = (MATCH) fieldWeight(description:book in 1), product of:
          1.0 = tf(termFreq(description:book)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.25 = fieldNorm(field=description, doc=1)
&lt;/str&gt;
    &lt;str name="1"&gt;
0.073365316 = (MATCH) sum of:
  0.073365316 = (MATCH) sum of:
    7.1670645E-4 = (MATCH) max plus 0.01 times others of:
      7.163483E-4 = (MATCH) weight(author:joe^10.0 in 0), product of:
        0.0024097771 = queryWeight(author:joe^10.0), product of:
          10.0 = boost
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0532142E-4 = queryNorm
        0.29726744 = (MATCH) fieldWeight(author:joe in 0), product of:
          1.0 = tf(termFreq(author:joe)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.5 = fieldNorm(field=author, doc=0)
      3.5817415E-5 = (MATCH) weight(description:joe in 0), product of:
        2.4097772E-4 = queryWeight(description:joe), product of:
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0532142E-4 = queryNorm
        0.14863372 = (MATCH) fieldWeight(description:joe in 0), product of:
          1.0 = tf(termFreq(description:joe)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.25 = fieldNorm(field=description, doc=0)
    0.0010134276 = (MATCH) max plus 0.01 times others of:
      0.0010130694 = (MATCH) weight(author:blow^10.0 in 0), product of:
        0.0024097771 = queryWeight(author:blow^10.0), product of:
          10.0 = boost
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0532142E-4 = queryNorm
        0.42039964 = (MATCH) fieldWeight(author:blow in 0), product of:
          1.4142135 = tf(termFreq(author:blow)=2)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.5 = fieldNorm(field=author, doc=0)
      3.5817415E-5 = (MATCH) weight(description:blow in 0), product of:
        2.4097772E-4 = queryWeight(description:blow), product of:
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0532142E-4 = queryNorm
        0.14863372 = (MATCH) fieldWeight(description:blow in 0), product of:
          1.0 = tf(termFreq(description:blow)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.25 = fieldNorm(field=description, doc=0)
    0.07163518 = (MATCH) max plus 0.01 times others of:
      0.07163482 = (MATCH) weight(title:book^1000.0 in 0), product of:
        0.2409777 = queryWeight(title:book^1000.0), product of:
          1000.0 = boost
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0532142E-4 = queryNorm
        0.29726744 = (MATCH) fieldWeight(title:book in 0), product of:
          1.0 = tf(termFreq(title:book)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.5 = fieldNorm(field=title, doc=0)
      3.5817415E-5 = (MATCH) weight(description:book in 0), product of:
        2.4097772E-4 = queryWeight(description:book), product of:
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0532142E-4 = queryNorm
        0.14863372 = (MATCH) fieldWeight(description:book in 0), product of:
          1.0 = tf(termFreq(description:book)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.25 = fieldNorm(field=description, doc=0)
    &lt;/str&gt;
  &lt;/lst&gt;
&lt;/lst&gt;
&lt;/response&gt;</pre>
<h4 class="brush:xml">Pierwszy dokument</h4>
<p><a href="http://solr.pl/wp-content/uploads/2012/02/tie001_doc12.png"><img fetchpriority="high" decoding="async" class="alignnone size-full wp-image-2088" title="tie001_doc1" src="http://solr.pl/wp-content/uploads/2012/02/tie001_doc12.png" alt="" width="600" height="248"></a></p>
<h4>Drugi dokument</h4>
<p><a href="http://solr.pl/wp-content/uploads/2012/02/tie001_doc21.png"><img decoding="async" class="alignnone size-full wp-image-2089" title="tie001_doc2" src="http://solr.pl/wp-content/uploads/2012/02/tie001_doc21.png" alt="" width="600" height="248"></a></p>
<h4>Czyli jak to wygląda ?</h4>
<p>Jak widać w przypadku przekazania wartości 0.01 do parametru <em>tie</em> pola, które mają najwyższy score, mają największe znaczenie, z niedużym znaczeniem innych pól. Widać to dobrze na przykładzie słowa <em>book</em> w pierwszym dokumencie na liście wyników. Score dla tego słowa, to <code></code><code>0.07163518</code>, na który został wyliczony jako suma pola, które ma najwyższy score dla tego słowa, czyli pola <em>title</em> oraz wartości score reszty pól pomnożonych przez wartość <em>tie</em>, czyli 0.01.</p>
<h3>Rezultat z tie == 0.99</h3>
<p>Drugie zapytanie wygląda w następujący sposób:
</p>
<pre class="brush:xml">defType=dismax&amp;qf=title^1000 description author^10&amp;tie=0.99&amp;fl=id,score&amp;debugQuery=on&amp;indent=true&amp;q=joe blow book</pre>
<p>Wyniki zwrócone przez Solr (wizualizacja &#8211; <a href="http://explain.solr.pl/explains/1w7b06lv" target="_blank" rel="noopener noreferrer">http://explain.solr.pl/explains/1w7b06lv</a>):
</p>
<pre class="brush:xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;response&gt;
&lt;lst name="responseHeader"&gt;
  &lt;int name="status"&gt;0&lt;/int&gt;
  &lt;int name="QTime"&gt;15&lt;/int&gt;
  &lt;lst name="params"&gt;
    &lt;str name="fl"&gt;id,score&lt;/str&gt;
    &lt;str name="debugQuery"&gt;on&lt;/str&gt;
    &lt;str name="indent"&gt;true&lt;/str&gt;
    &lt;str name="tie"&gt;0.99&lt;/str&gt;
    &lt;str name="q"&gt;joe blow book&lt;/str&gt;
    &lt;str name="qf"&gt;title^1000 description author^10&lt;/str&gt;
    &lt;str name="defType"&gt;dismax&lt;/str&gt;
  &lt;/lst&gt;
&lt;/lst&gt;
&lt;result name="response" numFound="2" start="0" maxScore="0.07352995"&gt;
  &lt;doc&gt;
    &lt;float name="score"&gt;0.07352995&lt;/float&gt;
    &lt;str name="id"&gt;2&lt;/str&gt;
  &lt;/doc&gt;
  &lt;doc&gt;
    &lt;float name="score"&gt;0.0734685&lt;/float&gt;
    &lt;str name="id"&gt;1&lt;/str&gt;
  &lt;/doc&gt;
&lt;/result&gt;
&lt;lst name="debug"&gt;
  &lt;str name="rawquerystring"&gt;joe blow book&lt;/str&gt;
  &lt;str name="querystring"&gt;joe blow book&lt;/str&gt;
  &lt;str name="parsedquery"&gt;+((DisjunctionMaxQuery((author:joe^10.0 | title:joe^1000.0 | description:joe)~0.99) DisjunctionMaxQuery((author:blow^10.0 | title:blow^1000.0 | description:blow)~0.99) DisjunctionMaxQuery((author:book^10.0 | title:book^1000.0 | description:book)~0.99))~3) ()&lt;/str&gt;
  &lt;str name="parsedquery_toString"&gt;+(((author:joe^10.0 | title:joe^1000.0 | description:joe)~0.99 (author:blow^10.0 | title:blow^1000.0 | description:blow)~0.99 (author:book^10.0 | title:book^1000.0 | description:book)~0.99)~3) ()&lt;/str&gt;
  &lt;lst name="explain"&gt;
    &lt;str name="2"&gt;
0.07352995 = (MATCH) sum of:
  0.07352995 = (MATCH) sum of:
    9.308678E-4 = (MATCH) max plus 0.99 times others of:
      8.9540955E-4 = (MATCH) weight(author:joe^10.0 in 1), product of:
        0.0024097078 = queryWeight(author:joe^10.0), product of:
          10.0 = boost
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0530972E-4 = queryNorm
        0.3715843 = (MATCH) fieldWeight(author:joe in 1), product of:
          1.0 = tf(termFreq(author:joe)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.625 = fieldNorm(field=author, doc=1)
      3.581638E-5 = (MATCH) weight(description:joe in 1), product of:
        2.4097077E-4 = queryWeight(description:joe), product of:
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0530972E-4 = queryNorm
        0.14863372 = (MATCH) fieldWeight(description:joe in 1), product of:
          1.0 = tf(termFreq(description:joe)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.25 = fieldNorm(field=description, doc=1)
    9.308678E-4 = (MATCH) max plus 0.99 times others of:
      8.9540955E-4 = (MATCH) weight(author:blow^10.0 in 1), product of:
        0.0024097078 = queryWeight(author:blow^10.0), product of:
          10.0 = boost
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0530972E-4 = queryNorm
        0.3715843 = (MATCH) fieldWeight(author:blow in 1), product of:
          1.0 = tf(termFreq(author:blow)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.625 = fieldNorm(field=author, doc=1)
      3.581638E-5 = (MATCH) weight(description:blow in 1), product of:
        2.4097077E-4 = queryWeight(description:blow), product of:
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0530972E-4 = queryNorm
        0.14863372 = (MATCH) fieldWeight(description:blow in 1), product of:
          1.0 = tf(termFreq(description:blow)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.25 = fieldNorm(field=description, doc=1)
    0.071668215 = (MATCH) max plus 0.99 times others of:
      0.07163276 = (MATCH) weight(title:book^1000.0 in 1), product of:
        0.24097076 = queryWeight(title:book^1000.0), product of:
          1000.0 = boost
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0530972E-4 = queryNorm
        0.29726744 = (MATCH) fieldWeight(title:book in 1), product of:
          1.0 = tf(termFreq(title:book)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.5 = fieldNorm(field=title, doc=1)
      3.581638E-5 = (MATCH) weight(description:book in 1), product of:
        2.4097077E-4 = queryWeight(description:book), product of:
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0530972E-4 = queryNorm
        0.14863372 = (MATCH) fieldWeight(description:book in 1), product of:
          1.0 = tf(termFreq(description:book)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.25 = fieldNorm(field=description, doc=1)
&lt;/str&gt;
    &lt;str name="1"&gt;
0.0734685 = (MATCH) sum of:
  0.0734685 = (MATCH) sum of:
    7.517859E-4 = (MATCH) max plus 0.99 times others of:
      7.1632763E-4 = (MATCH) weight(author:joe^10.0 in 0), product of:
        0.0024097078 = queryWeight(author:joe^10.0), product of:
          10.0 = boost
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0530972E-4 = queryNorm
        0.29726744 = (MATCH) fieldWeight(author:joe in 0), product of:
          1.0 = tf(termFreq(author:joe)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.5 = fieldNorm(field=author, doc=0)
      3.581638E-5 = (MATCH) weight(description:joe in 0), product of:
        2.4097077E-4 = queryWeight(description:joe), product of:
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0530972E-4 = queryNorm
        0.14863372 = (MATCH) fieldWeight(description:joe in 0), product of:
          1.0 = tf(termFreq(description:joe)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.25 = fieldNorm(field=description, doc=0)
    0.0010484984 = (MATCH) max plus 0.99 times others of:
      0.0010130403 = (MATCH) weight(author:blow^10.0 in 0), product of:
        0.0024097078 = queryWeight(author:blow^10.0), product of:
          10.0 = boost
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0530972E-4 = queryNorm
        0.42039964 = (MATCH) fieldWeight(author:blow in 0), product of:
          1.4142135 = tf(termFreq(author:blow)=2)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.5 = fieldNorm(field=author, doc=0)
      3.581638E-5 = (MATCH) weight(description:blow in 0), product of:
        2.4097077E-4 = queryWeight(description:blow), product of:
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0530972E-4 = queryNorm
        0.14863372 = (MATCH) fieldWeight(description:blow in 0), product of:
          1.0 = tf(termFreq(description:blow)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.25 = fieldNorm(field=description, doc=0)
    0.071668215 = (MATCH) max plus 0.99 times others of:
      0.07163276 = (MATCH) weight(title:book^1000.0 in 0), product of:
        0.24097076 = queryWeight(title:book^1000.0), product of:
          1000.0 = boost
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0530972E-4 = queryNorm
        0.29726744 = (MATCH) fieldWeight(title:book in 0), product of:
          1.0 = tf(termFreq(title:book)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.5 = fieldNorm(field=title, doc=0)
      3.581638E-5 = (MATCH) weight(description:book in 0), product of:
        2.4097077E-4 = queryWeight(description:book), product of:
          0.5945349 = idf(docFreq=2, maxDocs=2)
          4.0530972E-4 = queryNorm
        0.14863372 = (MATCH) fieldWeight(description:book in 0), product of:
          1.0 = tf(termFreq(description:book)=1)
          0.5945349 = idf(docFreq=2, maxDocs=2)
          0.25 = fieldNorm(field=description, doc=0)
    &lt;/str&gt;
  &lt;/lst&gt;
&lt;/lst&gt;
&lt;/response&gt;</pre>
<h4>Pierwszy dokument</h4>
<p><a href="http://solr.pl/wp-content/uploads/2012/02/tie099_doc11.png"><img decoding="async" class="alignnone size-full wp-image-2091" title="tie099_doc1" src="http://solr.pl/wp-content/uploads/2012/02/tie099_doc11.png" alt="" width="600" height="245"></a></p>
<h4>Drugi dokument</h4>
<p><a href="http://solr.pl/wp-content/uploads/2012/02/tie099_doc21.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-2092" title="tie099_doc2" src="http://solr.pl/wp-content/uploads/2012/02/tie099_doc21.png" alt="" width="600" height="248"></a></p>
<h4>Czyli jak to wygląda ?</h4>
<p>Jak widać, score poszczególnych dokumentów uległ zmianie. Spójrzmy na ten sam dokument i te same słowo <em>book</em>. W przypadku, kiedy przekazaliśmy wartość 0.99 jako wartość parametru <em>tie</em>, wartość score zwiększyła się w stosunku do tej, którą obserwowaliśmy w przypadku <em>tie</em> równego 0.01. Oczywiście na zmianę wartości score ma także wpływ współczynnik normalizacji, ale pomińmy go w celu uproszczenia <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;" /> Zatem w drugim przypadku obserwujemy score wynoszący <code></code><code>0.071668215</code>, składa się na to wartość score dla pola <em>title</em> oraz suma wartości score dla każdego z pozostałych pól, ale tym razem pomnożonych przez wartość 0.99.</p>
<h3>Podsumowując</h3>
<p>Jak widać, parametr <em>tie</em>&nbsp;pozwala nam na dość dużą kontrolę tego, jak wyliczany jest score w przypadku DisjunctionMaxQuery. W ekstremalnym przypadku, kiedy chcielibyśmy, aby tylko pola, które mają najwyższy score miały znaczenie, możemy ustawić parametr <em>tie</em> na wartość 0.0. <em>Tie</em> pozwala nam na kontrolę tego, czy chcemy, aby mało znaczące pola, po których wyszukujemy, wpływały na wartość score dokumentów, a tym samym na ich pozycję na liście wyników wyszukiwania kiedy korzystamy z Dismax&#8217;a.</p>
<h3>Na koniec</h3>
<p>Jeżeli zastanawiasz się z pomocą czego wygenerowaliśmy wykresy, które widoczne są w treści, zapraszamy na&nbsp;<a href="http://explain.solr.pl/help" target="_blank" rel="noopener noreferrer">http://explain.solr.pl/help</a>, może&nbsp;<a href="http://explain.solr.pl/" target="_blank" rel="noopener noreferrer">http://explain.solr.pl/</a> będzie przydatne w Twoim przypadku.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://solr.pl/2012/02/06/do-czego-moze-przydac-sie-tie-w-dismaxie/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Czy muszę uważać na limit związany z maxBooleanClauses korzystając z filtrów ?</title>
		<link>https://solr.pl/2011/12/19/czy-musze-uwazac-na-limit-zwiazany-z-maxbooleanclauses-korzystajac-z-filtrow/</link>
					<comments>https://solr.pl/2011/12/19/czy-musze-uwazac-na-limit-zwiazany-z-maxbooleanclauses-korzystajac-z-filtrow/#respond</comments>
		
		<dc:creator><![CDATA[Rafał Kuć]]></dc:creator>
		<pubDate>Mon, 19 Dec 2011 20:34:02 +0000</pubDate>
				<category><![CDATA[Solr]]></category>
		<category><![CDATA[boolean]]></category>
		<category><![CDATA[boolean query]]></category>
		<category><![CDATA[clause]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[max]]></category>
		<category><![CDATA[maxBooleanClause]]></category>
		<category><![CDATA[query]]></category>
		<category><![CDATA[solr]]></category>
		<guid isPermaLink="false">http://sematext.solr.pl/?p=339</guid>

					<description><![CDATA[Jedną ze zmiennych konfiguracyjnych, jakie znajdują się w pliku solrconfig.xml jest maxBooleanClauses, która określa maksymalną ilość zapytań boolowskich jaka może być zwarta w ramach pojedynczego zapytania do Solr. Czy muszę uważać na limit związany z tą zmienną korzystając z filtrów]]></description>
										<content:encoded><![CDATA[<p>Jedną ze zmiennych konfiguracyjnych, jakie znajdują się w pliku <em>solrconfig.xml</em> jest <em>maxBooleanClauses</em>, która określa maksymalną ilość zapytań boolowskich jaka może być zwarta w ramach pojedynczego zapytania do Solr. Czy muszę uważać na limit związany z tą zmienną korzystając z filtrów w Solr ? Spróbujmy odpowiedź na to pytanie nie wgłębiając się w kod Lucene i Solr.</p>
<p><span id="more-339"></span></p>
<h3><zapytanie< h3=""></p>
<p>Załóżmy, że standardowo zadawaliśmy następujące zapytanie do Solr:
</p>
<pre class="brush:xml">q=category:1 AND category:2 AND category:3 ... AND category:2000</pre>
<p>Zadanie takiego zapytania z domyślną konfiguracją Solr będzie skutkowało wyjątkiem i komunikatem &#8222;<em>too many boolean clauses</em>&#8222;. Oczywiście, moglibyśmy zmodyfikować opcję <em>maxBooleanClauses</em> i pozbyć się wyjątku, jednak spróbujmy zrobić to w inny sposób:</p>
<h3>Zmieńmy zapytanie na filtry</h3>
<p>Zmieńmy zatem powyższe zapytanie tak, aby wykorzystywało filtry, czyli parametr <em>fq</em>:
</p>
<pre class="brush:xml">q=*:*&amp;fq=category:(1 2 3 ... 2000)</pre>
<p>Wysyłamy powyższe zapytanie i &#8230; i znów to samo &#8211; wyjątek i komunikat &#8222;<em>too many boolean clauses</em>&#8222;. Dzieje się tak dlatego, iż Solr musi &#8222;wyliczyć&#8221; zawartość filtra, a co za tym idzie skonstruować odpowiednie zapytanie. Dokonajmy zatem jeszcze jednej modyfikacji:</p>
<h3>Kolejna modyfikacja zapytania</h3>
<p>Niech nasze zapytanie wygląda w takim wypadku w następujący sposób:
</p>
<pre class="brush:xml">q=*:*&amp;fq=category:1&amp;fq=category:2&amp;fq=category:3&amp;....&amp;fq=category:2000</pre>
<p>Po wysłaniu zmodyfikowanego zapytania naszym oczom ukażą się wyniki wyszukiwania (oczywiście, jeżeli w indeksie znajdują się dokumenty odpowiadające warunkom w zapytaniu). Tym razem Solr nie musiał składać jednego dużego zapytania, dlatego też nie przekroczyliśmy limitu związanego z <em>maxBooleanClauses</em>.</p>
<h3>Podsumowanie</h3>
<p>Jak widać odpowiedź na pytanie zależy od tego, jakie zapytanie chcemy, bądź musimy zadać. W przypadku, kiedy nasze warunki łączy operator logiczny <em>AND</em> możemy pozwolić sobie na zmianę zapytania na wiele parametrów <em>fq</em> ponieważ Solr łączy je automatycznie właśnie tym spójnikiem. Jeżeli natomiast zmuszeni jesteśmy stosować spójnik logiczny <em>OR</em> czekałaby nas zmiana limitu wyznaczonego przez <em>maxBooleanClauses</em>. Należy przy tym pamiętać, iż zwiększanie tego limitu może pociągnąć za sobą spadek wydajności i zwiększone wykorzystanie pamięci.</p>
</p>
<p></zapytanie<></h3>
]]></content:encoded>
					
					<wfw:commentRss>https://solr.pl/2011/12/19/czy-musze-uwazac-na-limit-zwiazany-z-maxbooleanclauses-korzystajac-z-filtrow/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Krótkie spojrzenie: frange</title>
		<link>https://solr.pl/2011/05/30/krotkie-spojrzenie-frange/</link>
					<comments>https://solr.pl/2011/05/30/krotkie-spojrzenie-frange/#respond</comments>
		
		<dc:creator><![CDATA[Rafał Kuć]]></dc:creator>
		<pubDate>Mon, 30 May 2011 17:46:42 +0000</pubDate>
				<category><![CDATA[Ogólna]]></category>
		<category><![CDATA[frange]]></category>
		<category><![CDATA[query]]></category>
		<category><![CDATA[range]]></category>
		<category><![CDATA[solr]]></category>
		<guid isPermaLink="false">http://sematext.solr.pl/?p=244</guid>

					<description><![CDATA[W Solr 1.4 pojawił się nowy typ zapytań funkcyjnych zwanych frange. Służą one do wyszukiwania informacji z danego przedziału. Według twórców Solr zapytania te powinny być znacznie szybsze (w niektórych przypadkach testy wykazały nawet 40-krotny wzrost wydajności) od zwykłych zapytań.]]></description>
										<content:encoded><![CDATA[<p>W Solr 1.4 pojawił się nowy typ <em>zapytań funkcyjnych </em>zwanych <em>frange. </em>Służą one do wyszukiwania informacji z danego przedziału. Według twórców Solr zapytania te powinny być znacznie szybsze (w niektórych przypadkach testy wykazały nawet 40-krotny wzrost wydajności) od zwykłych zapytań. Stwierdziłem, że przeprowadzę prosty test sprawdzający, czy można spodziewać się takich wzrostów wydajności w przypadku zapytań o przedziały.</p>
<p><span id="more-244"></span></p>
<h2>Zadawanie zapytań</h2>
<p>Aby skorzystać z zapytań <em>frange</em> należy zmodyfikować składnię zapytania. Do tej pory, zapytanie o zakres danych mogło wyglądać w następujący sposób:
</p>
<pre class="brush:xml">fq=test_si:[0+TO+10000]</pre>
<p>w tym momencie, należy zadać to zapytanie w poniższy sposób:
</p>
<pre class="brush:xml">fq={!frange l=0 u=10000}test_si</pre>
<p>Oczywiście, możliwe jest również składanie zapytań o zakresy inne, niż liczbowe, na przykład:
</p>
<pre class="brush:xml">fq={!frange l=adam u=mariusz}imie</pre>
<h2>Wydajność</h2>
<p>Sama logika testu jest dość prosta. Struktura indeksu zawiera dwa pola: <em>id</em>, czyli unikalny identyfikator oraz pole <em>namestr </em>(typu String) w którym generuje wartości o które będę się pytał. Zaindeksowałem w ten sposób 100.000 dokumentów. Dodatkowo w każdym z dokumentów termy w polach są unikalne, tak, aby w łatwy sposób móc określić procent termów pokrytych przez dane zapytanie. Następnie zacząłem zadawać zapytania pokrywające pewien procent termów w indeksie. Każde zapytanie zadawałem kilkukrotnie uśredniając wyniki. Poniższa tabela ilustruje wynik testu:</p>
[table “5” not found /]<br />

<p>Jak widać standardowe zapytanie o przedział danych jest szybsze tylko w przypadku zapytania, które pokrywa małą ilość termów w polu. Już od 5% termów nowy typ zapytań o przedział jest dużo szybszy, co widać w przypadku większego pokrycia, np. 50%. Co ciekawe uzyskujemy wzrost wydajności kilkukrotny, co napawa optymizmem na jeszcze szybsze wyszukiwanie.</p>
<h2>Na koniec</h2>
<p>Wyniki mojego testu różnią się pod względem wydajności z tym co napisał Yonik Seeley na swoim blogu (wiąże się to m.in. z tym, że dane były przygotowane szybko), jednak co by nie mówić, testy pokazują wzrost wydajności w przypadku zapytań wykorzystujących <em>frange</em>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://solr.pl/2011/05/30/krotkie-spojrzenie-frange/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Kilka słów o optymalizacji &#8211; filter cache</title>
		<link>https://solr.pl/2011/02/07/kilka-slow-o-optymalizacji-filter-cache/</link>
					<comments>https://solr.pl/2011/02/07/kilka-slow-o-optymalizacji-filter-cache/#respond</comments>
		
		<dc:creator><![CDATA[Rafał Kuć]]></dc:creator>
		<pubDate>Mon, 07 Feb 2011 08:02:49 +0000</pubDate>
				<category><![CDATA[Solr]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[filter cache]]></category>
		<category><![CDATA[filterCache]]></category>
		<category><![CDATA[filtr]]></category>
		<category><![CDATA[filtrowanie]]></category>
		<category><![CDATA[query]]></category>
		<guid isPermaLink="false">http://sematext.solr.pl/?p=180</guid>

					<description><![CDATA[Dzisiejszy wpis poświęcony został jednemu z typów cache w Solr &#8211; filter cache. Postaram się przedstawić do czego służy, jak go skonfigurować i jak go optymalnie wykorzystywać. Zapraszam do lektury. Co przechowuje Zacznijmy od środka. FilterCache przechowuje nieuporządkowany zbiór identyfikatorów]]></description>
										<content:encoded><![CDATA[<p>Dzisiejszy wpis poświęcony został jednemu z typów cache w Solr &#8211; filter cache. Postaram się przedstawić do czego służy, jak go skonfigurować i jak go optymalnie wykorzystywać. Zapraszam do lektury.</p>
<p><span id="more-180"></span></p>
<h3>Co przechowuje</h3>
<p>Zacznijmy od środka. FilterCache przechowuje nieuporządkowany zbiór identyfikatorów dokumentów. Oczywiście nie są to identyfikatory zdefiniowanie w pliku <em>schema.xml</em> jako unikalny klucz, a wewnętrzne identyfikatory dokumentów używane przez Lucene i Solr &#8211; warto o tym pamiętać.</p>
<h3>Do czego służy</h3>
<p>Głównym zadaniem <em>filterCache </em>jest przechowywanie wyników związanych z wykorzystaniem filtrów. Aczkolwiek nie jest to jego jedyne zastosowanie. Oprócz tego cache ten może służyć jako pomoc przy facetingu (w przypadku korzystania z metody <em>TermEnum</em>) oraz do sortowania w przypadku określenia opcji <em>&lt;useFilterForSortedQuery/&gt;</em> na <em>true</em> w pliku<em> solrconfig.xml</em>.</p>
<h3>Definicja</h3>
<p>Standardowa definicja filterCache wygląda następująco:
</p>
<pre class="brush:xml">&lt;filterCache
      class="solr.FastLRUCache"
      size="16384"
      initialSize="4096"
      autowarmCount="4096" /&gt;</pre>
<p>Dostępne są następujące opcje konfiguracyjne:</p>
<ul>
<li><em>class </em>&#8211; klasa odpowiadająca za implementację. Do <em>filterCache </em>polecam korzystanie z <em>solr.FastLRUCache</em>, który charakteryzuje się większą wydajnością w przypadku większej ilości operacji GET, niż PUT.</li>
<li><em>size </em>&#8211; maksymalna ilość wpisów jaka może znaleźć się w cache&#8217;u.</li>
<li><em>initialSize </em>&#8211; początkowa wielkość cache&#8217;u.</li>
<li><em>autowarmCount </em>&#8211; ilość wpisów jaka będzie przepisywana podczas rozgrzewania ze starego cache&#8217;u do nowego.</li>
<li><em>minSize </em>&#8211; wartość określająca do jakiej ilości wpisów Solr będzie próbował redukować cache w przypadku pełnego uzupełnienia.</li>
<li><em>acceptableSize </em>&#8211; jeżeli Solr nie będzie w stanie sprowadzić ilości wpisów do tej określonej za pomocą parametru <em>minSize</em>, to wartość <em>acceptableSize</em> będzie tą, do której będzie dążył jako kolejnej.</li>
<li><em>cleanupThread </em>&#8211; wartość domyślna to <em>false</em>. W przypadku ustawienia na <em>true</em> do czyszczenia cache&#8217;u będzie wykorzystywany oddzielny wątek.</li>
</ul>
<p>W większości przypadków wykorzystanie parametrów <em>size</em>, <em>initialSize</em> oraz <em>autowarmCount </em>jest w zupełności wystarczające.</p>
<h3>Jak skonfigurować</h3>
<p>Wielkość cache&#8217;u powinna być określana na podstawie zapytań, które wysyłane są do Solr. Maksymalna wielkość <em>filterCache </em>powinna być przynajmniej tak duża jak ilość filtrów (wraz z wartościami) jaką wykorzystujemy. Oznacza to, że jeżeli nasza aplikacja charakteryzuje się, w zadanym okresie czasu, wykorzystaniem np. 2000 różnych filtrów (parametrów <em>fq</em> wraz z wartościami), to parametr <em>size</em> powinien być ustawiony na wartości minimum 2000.</p>
<h3>Efektywne wykorzystanie</h3>
<p>Jednak samo skonfigurowanie cache&#8217;u to nie koniec &#8211; ważne, aby zapytania potrafiły to wykorzystać. Weźmy na przykład zapytanie:
</p>
<pre class="brush:xml">q=nazwa:solr+AND+kategoria:ksiazka+AND+dzial:ksiazki</pre>
<p>Na pierwszy rzut oka zapytanie jest jak najbardziej poprawne. Jest z nim jednak jeden problem &#8211; nie korzysta z <em>filterCache</em>. Całe zapytanie zostanie obsłużone przez <em>queryResultCache</em> i stworzy w nim pojedynczy wpis. Zmodyfikujemy je trochę i zadajmy je w następujący sposób.
</p>
<pre class="brush:xml">q=nazwa:solr&amp;fq=kategoria:ksiazka&amp;fq=dzial:ksiazki</pre>
<p>Co się stanie teraz ? Tak jak w poprzednim wypadku, stworzony zostanie jeden wpis w <em>queryResultCache</em> oraz dwa wpisy w <em>filterCache</em>. Dlaczego jest to ważne ? Weźmy kolejne zapytanie:
</p>
<pre class="brush:xml">q=nazwa:lucene&amp;fq=kategoria:ksiazka&amp;fq=dzial:ksiazki</pre>
<p>To zapytanie stworzyłoby kolejny wpis w <em>queryResultCache</em> oraz wykorzystałoby dwa już istniejące w <em>filterCache</em> wpisy, a tym samym Solr skróciłbym czas wykonania zapytaniai oszczędziłby operacji I/O na indeksie.</p>
<p>Jeżeli natomiast wykonalibyśmy zapytanie w postaci:
</p>
<pre class="brush:xml">q=nazwa:lucene+AND+kategoria:ksiazka+AND+dzial:ksiazki</pre>
<p>Solr nie byłby w stanie wykorzystać żadnych informacji z cache&#8217;u i musiałby w celu zalezienia wyników pobierać wszystkie informacje z indeksu Lucene.</p>
<h3>Kilka słów na koniec</h3>
<p>Jak widać, samo skonfigurowanie cache&#8217;u w poprawny sposób nie gwarantuje tego, że Solr będzie w stanie go wykorzystać. To od tego jak zadajemy zapytania zależy, jak wydajny w docelowym wdrożeniu będzie Solr. Warto o tym pamiętać podczas planowania wdrożenia.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://solr.pl/2011/02/07/kilka-slow-o-optymalizacji-filter-cache/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Kilka słow o optymalizacji &#8211; query result window size</title>
		<link>https://solr.pl/2011/01/10/kilka-slow-o-optymalizacji-query-result-window-size/</link>
					<comments>https://solr.pl/2011/01/10/kilka-slow-o-optymalizacji-query-result-window-size/#respond</comments>
		
		<dc:creator><![CDATA[Rafał Kuć]]></dc:creator>
		<pubDate>Mon, 10 Jan 2011 07:59:20 +0000</pubDate>
				<category><![CDATA[Ogólna]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[query]]></category>
		<category><![CDATA[query result]]></category>
		<category><![CDATA[queryResultCache]]></category>
		<category><![CDATA[queryResultWindowSize]]></category>
		<category><![CDATA[result]]></category>
		<category><![CDATA[size]]></category>
		<guid isPermaLink="false">http://sematext.solr.pl/?p=174</guid>

					<description><![CDATA[Niniejszym chciałbym rozpocząć mały cykl artykułów opisujący elementy optymalizacji instancji Solr. Na pierwszy rzut pójdzie parametr określający tzw. wielkość okna danych, czyli inaczej query result window. Miejmy nadzieję, że tym artykułem będę w stanie wyjaśnić jak korzystać z tego parametru]]></description>
										<content:encoded><![CDATA[<p>Niniejszym chciałbym rozpocząć mały cykl artykułów opisujący elementy optymalizacji instancji Solr. Na pierwszy rzut pójdzie parametr określający tzw. wielkość okna danych, czyli inaczej query result window. Miejmy nadzieję, że tym artykułem będę w stanie wyjaśnić jak korzystać z tego parametru i jak modyfikować i dostosowywać go do swoich potrzeb.</p>
<p><span id="more-174"></span></p>
<h3>Na początek</h3>
<p>Aby zacząć mówić o konfiguracji parametru należy najpierw powiedzieć w jaki sposób Solr pobiera wyniki za pomocą biblioteki Lucene. Przekazując, wraz z zapytaniem do Solr, parametr <em>rows </em>z wartością np. 20 określamy, iż chcemy aby Solr zwrócił listę wyników składającą się maksymalnie z 20 dokumentów i tyle właśnie widzimy na wynikowej liście. Jednak ilość wyników, jaka została pobrana z indeksu jest różna i określona jest właśnie parametrem <em>queryResultWindowSize</em>. To ten parametr, zapisany w pliku <em>solrconfig.xml</em>, określa jak dużo wyników zostanie pobranych z indeksu i przechowanych w <em>queryResultCache</em>.</p>
<h3>Ale do czego służy <em>queryResultWindowSize</em> ?</h3>
<p>Parametr <em>queryResultWindowSize</em> określa wielkość, tzw. okna wyników, czyli po prostu ilość dokumentów jaka zostanie pobrana przy pobieraniu wyników wyszukiwania.&nbsp; Na przykład ustawiając <em>queryResultWinwdowSize</em> na wartość 100 i zadając zapytanie:
</p>
<pre class="brush:xml">q=car&amp;rows=30&amp;start=10</pre>
<p>na liście wyników wyszukiwania otrzymamy maksymalnie 20 dokumentów wynikowych, natomiast sam Solr pobierze tak naprawdę wyniki zaczynające się od indeksu 0, a kończące się na indeksie 100, a następnie spróbuje je umieścić w <em>queryResultCache</em>. Wyniki wyszukiwania kolejnych zapytań, różniących się jedynie parametrami <em>rows </em>i <em>start</em> będą mogły być pobierane z <em>queryResultCache</em>.</p>
<h3>Konfiguracja</h3>
<p>Aby ustawić <em>queryResultWindowSize</em> na pokazaną w powyższym przykładzie wartość 100, należy do pliku <em>solrconfig.xml</em> dodać następujący wpis:
</p>
<pre class="brush:xml">&lt;queryResultWindowSize&gt;100&lt;/queryResultWindowSize&gt;</pre>
<h3>O czym należy pamiętać ?</h3>
<p>Oczywiście samo ustawienie <em>queryResultsWindowSize</em> to nie jest wszystko. Należy jeszcze zapewnić odpowiednią ilość miejsca w <em>queryResultCache</em>, aby Solr miał możliwość przechowania koniecznych informacji. Natomiast sama konfiguracja <em>queryResultCache</em> to już temat na inny artykuł.</p>
<h3>Ale po co korzystać ?</h3>
<p>Odpowiedź na tak postawione pytanie jest całkiem proste &#8211; jeżeli Twoja aplikacja i Twoi użytkownicy często korzystają ze stronicowania rozsądnym będzie rozważenie zmiany domyślnej wartości <em>queryResultWindowSize</em>. W większości wypadków, gdzie wdrożenia opierały się na stronicowaniu, zmiana wartości omawianego parametru powodowała zwiększenie wydajności ciężkich zapytań przy przechodzeniu pomiędzy stronami wyników.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://solr.pl/2011/01/10/kilka-slow-o-optymalizacji-query-result-window-size/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>
	</channel>
</rss>
