<?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>routing &#8211; Solr.pl</title>
	<atom:link href="https://solr.pl/tag/routing/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>Sat, 14 Nov 2020 11:56:29 +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>Aliasy i Routing Na Podstawie Wartości Pola</title>
		<link>https://solr.pl/2019/10/21/aliasy-i-routing-na-podstawie-wartosci-pola/</link>
					<comments>https://solr.pl/2019/10/21/aliasy-i-routing-na-podstawie-wartosci-pola/#respond</comments>
		
		<dc:creator><![CDATA[Rafał Kuć]]></dc:creator>
		<pubDate>Mon, 21 Oct 2019 10:55:58 +0000</pubDate>
				<category><![CDATA[Solr]]></category>
		<category><![CDATA[kolekcja]]></category>
		<category><![CDATA[routing]]></category>
		<guid isPermaLink="false">http://sematext.solr.pl/?p=796</guid>

					<description><![CDATA[W trakcie całego życia Solr, jako silnika wyszukiwania, dostaliśmy możliwość pracy z rdzeniami, następnie z kolekcjami i aliasami &#8211; alternatywnymi nazwami kolekcji. Aliasy pozwalały na prostą separację prawdziwych nazw kolekcji oraz tego, co używa aplikacja. Dzięki temu możemy, posiadając wystarczającą]]></description>
										<content:encoded><![CDATA[
<p>W trakcie całego życia Solr, jako silnika wyszukiwania, dostaliśmy możliwość pracy z rdzeniami, następnie z kolekcjami i aliasami &#8211; alternatywnymi nazwami kolekcji. Aliasy pozwalały na prostą separację prawdziwych nazw kolekcji oraz tego, co używa aplikacja. Dzięki temu możemy, posiadając wystarczającą ilość zasobów sprzętowych, re-indeksować dane bez konieczności zatrzymywania aplikacji korzystającej z Solr lub powodowania przestojów. W Solr mamy opcję korzystania z dwóch typów aliasów:</p>



<span id="more-796"></span>



<ul class="wp-block-list"><li>standardowych aliasów grupujących kolekcję pod wirtualną nazwą, </li><li>aliasy routed, które automatycznie przekierowują żądania. </li></ul>



<p>Aliasy typu <em>routed</em> mogą być dalej podzielone na dwie kategorie &#8211; aliasy oparte o czas oraz aliasy oparte o wartość pola. W dzisiejszym wpisie skupimy się na tej drugiej kategorii. </p>



<h2 class="wp-block-heading">Dlaczego Potrzebujemy Aliasów Opartych O Wartość Pola</h2>



<p>Problemem standardowych aliasów jest indeksowanie. Kiedy tworzymy alias grupujący więcej, niż jedną kolekcję nie jesteśmy w stanie kontrolować, gdzie będą zaindeksowane nasze dokumenty. Na przykład, w Solr 8.2, nasze dokumenty zostaną zaindeksowane w pierwszej kolekcji zdefiniowanej przez alias. Zobaczmy to na przykładzie:</p>



<p>Zacznijmy od stworzenia dwóch kolekcji korzystając z API v2 Solr. Zaczynamy od pierwszej kolekcji:</p>



<pre class="wp-block-code"><code class="">curl -XPOST -H 'Content-type:application/json' 'http://localhost:8983/v2/c' -d '{ 
 "create" : {
  "name" : "test_1",
  "numShards" : 1,
  "replicationFactor" : 1
 }
}'</code></pre>



<p>A następnie tworzymy drugą kolekcję:</p>



<pre class="wp-block-code"><code class="">curl -XPOST -H 'Content-type:application/json' 'http://localhost:8983/v2/c' -d '{ 
 "create" : {
  "name" : "test_2",
  "numShards" : 1,
  "replicationFactor" : 1
 }
}'</code></pre>



<p>W tym momencie posiadamy w Solr dwie kolekcje &#8211; jedną nazwaną <em>test_1</em> oraz drugą nazwaną <em>test_2</em>. Możemy zatem stworzyć alias nazwany <em>test</em>, który będzie grupował obie kolekcje. W tym celu użyjemy następującego polecenia:</p>



<pre class="wp-block-code"><code class="">curl -XPOST -H 'Content-type:application/json' 'http://localhost:8983/v2/c' -d '{ 
 "create-alias" : {
  "name" : "test",
  "collections" : [ "test_1", "test_2" ]
 }
}'</code></pre>



<p>Wreszcie możemy zaindeksować dokument wykorzystując powyżej stworzony alias:</p>



<pre class="wp-block-code"><code class="">curl -XPOST -H 'Content-type:application/json' 'http://localhost:8983/solr/test/update?commit=true' -d '[
 {
  "id" : 1,
  "name" : "Test indexing"
 }
]'</code></pre>



<p>Powyższe polecenia zostanie pomyślnie wykonane w Solr 8.2, a sam dokument zostanie zaindeksowany w kolekcji <em>test_1</em>. Sprawdzenie tego pozostawiam Tobie, jako czytelnikowi <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>



<p>Aby poradzić sobie z problemem nieokreśloności, jeżeli chodzi o indeksowanie dokumentów możemy skorzystać z aliasów opartych o czas lub o wartość pola.</p>



<h2 class="wp-block-heading">Aliasy oparte o wartość pola</h2>



<p>Pomysł leżący u podstaw aliasów opartych o wartość pola, to grupowanie dokumentów w kolekcjach w oparciu o pewną wspólną wartość. Routing na poziomie pojedynczej kolekcji powoduje, iż dany <em>shard</em> przechowuje dane posiadające tą samą wartość routingu &#8211; na przykład dane pojedynczego użytkownika. W przypadku aliasów opartych o wartość pola Solr idzie o krok dalej &#8211; pojedyncza kolekcja będzie posiadała dane związane z daną wartością pola &#8211; na przykład dane użytkowników pojedynczej firmy. Potrzebne kolekcje będą tworzone automatycznie, a więc nie musimy się tym przejmować zarówno na etapie indeksowania, jak i zapytań.</p>



<figure class="wp-block-image"><img decoding="async" src="https://solr.pl/wp-content/uploads/2019/10/Category-Routing-Routing-1.png" alt="" class="wp-image-4740"/><figcaption>Uproszczona wersja routingu korzystającego z kategorii</figcaption></figure>



<h2 class="wp-block-heading">Tworzone aliasów opartych o wartość pola</h2>



<p>Tworzenie aliasów opartych o wartość pola jest trochę inne jeżeli porównamy to do standardowych aliasów. Nie zaczynamy procesu tworzenia od stworzenia kolekcji &#8211; te będą tworzone automatycznie. Zamiast tego zaczynamy od stworzenia definicji aliasu. </p>



<p>Stwórzmy nasz pierwszy alias oparty o wartość korzystając z następującego polecenia:</p>



<pre class="wp-block-code"><code class="">curl -XPOST -H 'Content-type:application/json' 'http://localhost:8983/v2/c' -d '{ 
 "create-alias" : {
  "name" : "test_cra_company",
  "router" : {
   "name" : "category",
   "field" : "company_name",
   "maxCardinality" : 2
  },
  "create-collection" : {
   "numShards" : "1",
   "replicationFactor" : "1",
   "config" : "_default"
  }
 }
}'</code></pre>



<p>Zatrzymajmy się na chwilę. Skorzystaliśmy z polecenia <em>create-alias</em> aby stworzyć nowy alias nazwany <em>test_cra_company</em>. Dodatkowo podaliśmy kilka atrybutów w celu zdefiniowania zachowania aliasu. Przyjrzyjmy się tym właściwościom.</p>



<ul class="wp-block-list"><li><em>name</em> &#8211; typ routera, który będzie wykorzystywany. W tej chwili Solr wspiera dwa typy: <em>time</em> oraz <em>category</em>. Pierwszy typ tworzy aliasy oparte o czas, drugi oparte o wartość pola.</li><li><em>field</em> &#8211; nazwa pola, które będzie wykorzystane do routingu. </li><li><em>maxCardinality</em> &#8211; maksymalna liczba unikalnych wartości w polu. Pozwala na ograniczenie liczby stworzonych kolekcji. </li></ul>



<p>Ponieważ nasz alias będzie tworzył kolekcje za nas, oprócz samego aliasu dodaliśmy sekcję <em>create-collection</em> zawierającą szereg parametrów określających jak będą wyglądać tworzone kolekcje. Warto pamiętać, iż jest taka możliwość.</p>



<p><strong>W powyższych przykładach, aby ograniczyć skomplikowanie przykłaów, skorzystaliśmy z domyślej konfiguracji kolekcji. Należy pamiętać, aby nie robić tego w środowisku produkcyjnym w przypadku korzystania z aliasów opartych o wartość pola.</strong></p>



<h2 class="wp-block-heading">Jak działa indeksowanie kiedy korzystamy z aliasów opartych o wartość pola?</h2>



<p>Kiedy Solr otrzymuje żądanie indeksowania korzysta z instancji klasy <em>UpdateRequestProcessor</em>. W przypadku SolrCloud, kiedy korzystamy ze standardowych aliasów Solr korzysta z instancji klasy <em>DistributedUpdateProcessor</em>. To ta klasa decyduje, gdzie dokument będzie finalnie umieszczony. W przypadku, kiedy korzystamy z aliasów opartych o wartość pola, przed instancją klasy <em>DistributedUpdateProcessor</em> Solr korzysta z klasy <em>RoutedAliasUpdateProcessor</em>. To ona decyduje, gdzie finalnie trafi nasz dokument, czyli tak naprawdę do której kolekcji. </p>



<p>W naszym przypadku, z powyżej stworzonym aliasem, zanim zostanie stworzona docelowa kolekcja, lub docelowe kolekcje specjalna kolkcja o nazwie <code>test_cra_company__CRA__NEW_CATEGORY_ROUTED_ALIAS_WAITING_FOR_DATA__TEMP</code> zostanie stworzona. W chwili kiedy dane zaczną być indeksowane Solr zacznie tworzyć kolekcje nazwane <code>test_cra_company__CRA__&lt;WARTOŚĆ_POLA&gt;</code>, na przykład <code>test_cra_company__CRA__company1</code> jeżeli wartość pola <code>company_name</code> będzie miała wartość <code>company1</code>. To powoduje, iż mamy pewne ograniczenia jeżeli chodzi o wartość pola używanego do tworzenia kolekcji, ale porozmawiamy o tym później.</p>



<h2 class="wp-block-heading">Indeksowanie danych używając aliasów opartych o wartość pola</h2>



<p>Zobaczmy teraz jak sprawują się aliasy oparte o wartość pola w akcji. Aby prezprowadzić prosty test zaindeksujemy dwa dokumenty korzystając z następujących komend:</p>



<pre class="wp-block-code"><code class="">curl -XPOST -H 'Content-type:application/json' 'http://localhost:8983/solr/test_cra_company/update?commit=true' -d '[
 {
  "id" : 1,
  "name" : "Test indexing",
  "company_name" : "company1"
 }
]'</code></pre>



<pre class="wp-block-code"><code class="">curl -XPOST -H 'Content-type:application/json' 'http://localhost:8983/solr/test_cra_company/update?commit=true' -d '[
 {
  "id" : 2,
  "name" : "Test indexing",
  "company_name" : "company2"
 }
]'</code></pre>



<p>Pamiętasz atrybut <em>maxCardinality</em>, który ustawiliśmy na wartość <em>2</em>? Jeżeli próbowalibyśmy zaindeksować dokument, który będzie miał kolejną, trzecią z rzędu wartość pola <em>company_name</em> Solr powinien zwrócić błąd. Na przykład skorzystajmy z następującego polecenia:</p>



<pre class="wp-block-code"><code class="">curl -XPOST -H 'Content-type:application/json' 'http://localhost:8983/solr/test_cra_company/update?commit=true' -d '[
 {
  "id" : 3,
  "name" : "Test indexing",
  "company_name" : "company3"
 }
]'</code></pre>



<p>Solr zwróci nam następujący błąd:</p>



<pre class="wp-block-code"><code class="">{
  "responseHeader":{
    "status":400,
    "QTime":1},
  "error":{
    "metadata":[
      "error-class","org.apache.solr.common.SolrException",
      "root-error-class","org.apache.solr.common.SolrException"],
    "msg":"Max cardinality 2 reached for Category Routed Alias: test_cra_company",
    "code":400}}</code></pre>



<h2 class="wp-block-heading">Zapytania</h2>



<p>Możemy także spróbować wyszukiwania, np. takiego, które zwróci wszystkie dokumenty:</p>



<pre class="wp-block-code"><code class="">http://localhost:8983/solr/test_cra_company/select?q=*:*</code></pre>



<p>W tym wypadku Solr zwróci następujący rezultat:</p>



<pre class="wp-block-code"><code class="">{
  "responseHeader": {
    "zkConnected": true,
    "status": 0,
    "QTime": 12,
    "params": {
      "q": "*:*"
    }
  },
  "response": {
    "numFound": 2,
    "start": 0,
    "maxScore": 1,
    "docs": [
      {
        "id": "1",
        "name": [
          "Test indexing"
        ],
        "company_name": [
          "company1"
        ],
        "_version_": 1647547697554522000
      },
      {
        "id": "2",
        "name": [
          "Test indexing"
        ],
        "company_name": [
          "company2"
        ],
        "_version_": 1647547721335177200
      }
    ]
  }
}</code></pre>



<p>Możemy korzystać z filtrów:</p>



<pre class="wp-block-code"><code class="">http://localhost:8983/solr/test_cra_company/select?q=*:*&amp;fq=company_name:company2</code></pre>



<p>W tym wypadku odpowiedź będzie zawierać tylko dokument, którego się spodziewamy:</p>



<pre class="wp-block-code"><code class="">{
  "responseHeader": {
    "zkConnected": true,
    "status": 0,
    "QTime": 25,
    "params": {
      "q": "*:*",
      "fq": "company_name:company2"
    }
  },
  "response": {
    "numFound": 1,
    "start": 0,
    "maxScore": 1,
    "docs": [
      {
        "id": "2",
        "name": [
          "Test indexing"
        ],
        "company_name": [
          "company2"
        ],
        "_version_": 1647547721335177200
      }
    ]
  }
}</code></pre>



<p>Jak widać wszystko działa tak, jakbyśmy się tego spodziewali. </p>



<p>Gwoli ścisłości, jeżeli chcielibyśmy wiedzieć, jakie kolekcje zostały stworzone to mamy je widoczne na poniższym obrazku:</p>



<figure class="wp-block-image"><img decoding="async" src="https://solr.pl/wp-content/uploads/2019/10/Screenshot-2019-10-16-at-14.44.43-1024x82.png" alt="" class="wp-image-4735"/></figure>



<h2 class="wp-block-heading">Ograniczenia</h2>



<p>Pisząc o funkcjonalności aliasów opartych o wartość pola należy wspomnieć o ich ograniczeniach.</p>



<p>Po pierwsze należy pamiętać o nazewnictwie. Do tworzenia kolekcji Solr korzysta z wartości znajdujących się w zdefiniowanym polu. Oznacza to, iż niektóre ze znaków UTF-8 mogą nie być obsługiwane i najlepiej trzymać się podstawowych znaków ASCII. W przeciwnym razie Solr może nie być w stanie stworzyć odpowiedniej kolekcji co może prowadzić do poważnych konsekwencji.</p>



<p>Drugim ograniczeniem jest usuwanie aliasu lub kolekcji w nim zawartych. Nie ma żadnej zautomatyzowanej funkcjonalności, która pozwoliłaby na usunięcie kolekcji z aliasu. Na przykład, jeżeli chcielibyśmy usunąć pojedynczą wartość z aliasu, czyli tak naprawdę kolekcję konieczne byłoby:</p>



<ul class="wp-block-list"><li>Upewnienie się, że nie będziemy już wysyłać dokumentów z wartością pola, którą chcemy usunąć.</li><li>Zmodyfikowanie aliasu, tak aby nie zawierał już kolekcji odpowiedzialnej za przechowywanie danych, które chcemy usunąć.</li><li>Usunięcie kolekcji korzystając z API Solr &#8211; musimy pamiętać o tym, że kolekcja musi być usunięcia z aliasu, zanim Solr pozwoli nam na fizyczne usunięcie kolekcji.</li></ul>



<p>W chwili publikowania tego wpisu, czyli w wersji 8.2 Solr, podczas indeksowania żądanie jest przekazywane do odpowiedniej kolekcji, natomiast wyszukiwanie uruchamiane jest na wszystkich kolekcjach, które grupowane są w ramach danego aliasu. Wysyłanie zapytań do kolekcji, które odpowiadają za przechowywanie danych dla danej wartości pola jest wymienione jako jedno z usprawnień możliwych do implementacji w przyszłości.</p>



<p>Ostatnia rzecz o jakiej należy pamiętać to tworzenie kolekcji. Nasz alias będzie tworzył kolekcję w chwili kiedy do Solr zostaną dostarczone dane z wartością pola dla którego kolekcja jeszcze nie istnieje. Należy pamiętać, iż tworzenie kolekcji trwa, czasem nawet do trzech sekund i zależy od obciążenia naszego klastra. Aplikacja indeksująca dane musi być zaimplementowana w sposób biorący to ograniczenie pod uwagę. </p>



<h2 class="wp-block-heading">Podsumowanie</h2>



<p>Jak widzimy aliasy oparte o wartość pola dostarczają bardzo fajnej metody automatycznego tworzenia kolekcji w oparciu o wartość dostarczaną w jednym z pól dokumentów. Jeżeli jest to coś czego potrzebujemy warto zastanowić się nad wykorzystaniem tej funkcjonalności, zwłaszcza w nowszych wersjach Solr. Czy ta funkcjonalność jest skończona i dopracowania &#8211; nie, dalej istnieją ograniczenia i możliwości optymalizacji o których wspomnieliśmy. Miejmy nadzieję, że zmiany te będą dostępne w następnych wersjach Solr.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://solr.pl/2019/10/21/aliasy-i-routing-na-podstawie-wartosci-pola/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
