Space Vatikán

když indexujete data, svět je zřídka tak jednoduchý jako každý dokument existující izolovaně. Někdy je lepší denormalizovat všechna data do podřízených dokumentů. Například pokud jste modelovali knihy, přidání pole autora do knih by mohlo být rozumnou volbou (i když v databázi, která je vaším autoritativním zdrojem dat, jsou data rozdělena na samostatnou tabulku authors a books). Je to jednoduché a můžete snadno vytvářet dotazy jak na atributy knihy, tak na jméno autora.

to není vždy praktické – v nadřazeném dokumentu může být příliš mnoho dat na to, aby se duplikovaly v každém podřízeném dokumentu. Pokud jste měli svůj typický blog / komentář app pak byste nechtěli opakovat celý obsah blogu v každém komentáři, protože by to výrazně zvýšit množství indexovaných dat několik. Přesto bez toho nemůžete snadno psát dotazy, abyste našli komentáře k příspěvkům, které odpovídají určitým kritériím (kromě toho, že provedete krok 2 procesu prvního nalezení odpovídajících příspěvků a poté načítání komentářů s určitým post_id, což je často nepraktické nebo pomalé (nebo obojí)).

další možností je umístit podřízené dokumenty do nadřazeného dokumentu, například můžete mít dokumenty formuláře

123456789101112
{ "name": "A. N Author", "biography": "A leading wordsmith", "books": }

jednou nevýhodou je, že přidání dítěte vyžaduje reindexování celého dokumentu. Najít autory, kteří napsali knihy s určitým žánrem, je snadné, ale najít autory, kteří měli knihu sci-fi vydanou Penguinem, je těžší.

pokud náš index obsahuje

pak nejviditelnější dotaz

najde oba autory – nemůžete vyjádřit, že vaše podmínky na published a genre se musí shodovat se stejnou knihou.

ElasticSearch poskytuje dvě věci, které s tím pomáhají. První je koncept vnořeného dokumentu / dotazu. To vám umožní říci, že hledáte autory, kde alespoň jedna kniha splňuje obě vaše kritéria.

nejprve je třeba nastavit mapování, které říká, že pole knihy bude vnořeno:

123456789
curl -XPOST localhost:9200/authors/nested_author/_mapping -d '{ "nested_author":{ "properties":{ "books": { "type": "nested" } } }}'

pokud do tohoto nového indexu vložíme stejná data jako dříve, pak tento dotaz

zde filtr nested umožňuje spustit dotaz proti vnořeným dokumentům (tj. knihám) a filtrovat autory podle těch, kteří mají alespoň jeden vnořený dokument odpovídající dotazu. Volba path nám říká, na kterou část dokumentu autorů se tento dotaz vztahuje, a pak volba query je dotaz, který se má spustit proti těmto vnořeným dokumentům. Na rozdíl od předchozího dotazu to vyžaduje, aby byla nalezena jednotlivá kniha splňující oba požadavky, takže je vrácen pouze Alaistair Reynolds

rodič & dítě

další koncept elasticsearch poskytuje vztah rodičů a dětí mezi dokumenty. Předchozí příklad lze přepracovat s autory jako nadřazené dokumenty a knihy jako podřízené dokumenty.

tentokrát indexujte autory odděleně od jejich knih:

poté nakonfigurujte mapování pro typ knihy a řekněte, že jeho nadřazený typ je bare_author. Musíte to udělat před vytvořením knih.

12345
curl -XPOST localhost:9200/authors/book/_mapping -d '{ "book":{ "_parent": {"type": "bare_author"} }}'

když jsme indexování knihy, pak musíte dát id svého rodiče (tj dodáváme id jednoho z dříve vytvořených autorů)

Elasticsearch poskytuje has_child filtr, který dělá skoro to, co se říká na tin: vybírá nadřazené dokumenty s alespoň jedním dítětem splňujícím určitý dotaz. Tento dotaz pak najde pouze Alastair Reynolds:

Solr 4.0 bude zřejmě mít schopnost dělat spojení, i když pokud vím, přichází s některými omezeními, zejména žádné spojení, Pokud jste provozováni v distribuovaném prostředí. Omezením se na vztahy typu rodič/dítě elasticsearch usnadňuje život pro sebe: dítě je vždy indexováno ve stejném střepu jako jeho rodič, takže has_child nemusí provádět nepříjemné křížové střepy.

seznamy budov

můžete také použít k modelování uživatelských seznamů sdílených globálních položek-např. pokud jste chtěli položky, které uživatel ohodnotil. V tomto případě by vaše podřízené dokumenty představovaly skutečnost, že konkrétní uživatel ohodnotil konkrétní příspěvek-nejsou ničím jiným než user_id, post_id a hodnocením: tabulka spojení v relační databázi žargon.

použití rodičovských / podřízených vztahů a has_child umožňuje snadno najít všechny příspěvky oblíbené uživatelem a zároveň umožňuje uživatelům prohledávat své oblíbené na základě obsahu příspěvku, data nebo jakéhokoli jiného atributu příspěvku nebo některého z vlastností podřízené položky. Přidání položky do seznamu hodnocených položek je levné-vyžaduje pouze indexování velmi malé položky rating.

s těmito dokumenty

tento dotaz

najde pouze „Bolívie hodnocené 4“, protože to je jediný příspěvek zmiňující Bolívii, který byl hodnocen přes 3 uživatelem, který nás zajímá. Dotaz nejvyšší úrovně na titul se vztahuje na příspěvky, kde dotaz uvnitř filtru has_child popisuje podmínky, které musí děti odpovídat (v tomto případě musí patřit konkrétnímu uživateli a mít alespoň určité hodnocení).

objednání

co has_child vám nedovolí udělat, je pořadí na základě atributů dětí nebo návratových atributů dítěte. Pokud jste chtěli objednat hodnocené příspěvky uživatele na základě toho, kdy byly hodnoceny nebo snížením hodnocení, můžete vyhledávat přímo proti příspěvkům / hodnocení, ale možná budete chtít na příspěvky použít i některá vyhledávací kritéria. Například budete chtít najít pouze hodnocené příspěvky na určité téma (stále objednávání podle hodnocení, které uživatel dal). S has_child máte smůlu. Vnořené dokumenty také nepomáhají.

od 0.19.10 můžete použít filtr has_parent. To funguje téměř přesně stejně jako má dítě, ale umožňuje zadat dotaz proti nadřazené položky namísto. Tento dotaz vrací hodnocení podle uživatele 1234, na příspěvcích, jejichž název odpovídá „Bolívii“, v sestupném pořadí skóre

to vrací objekty hodnocení – pak byste museli načíst odpovídající příspěvky samostatným dotazem.

předstírání

pokud jste přilepená na starší verzi elasticsearch, můžete získat většinu z cesty tam s top_children. Jak říká dokumentace top_children nejprve dotazuje podřízené dokumenty a poté je agreguje do nadřazených dokumentů. V našem příkladu to znamená, že elasticsearch nejprve najde dokumenty o hodnocení, které odpovídají našemu dotazu. Pak to bude odpovídat každé hodnocení na své mateřské místo, agregace duplicitní příspěvek, kde existují.

nešikovný bit s nejlepšími dětmi je, že elasticsearch neví dopředu, kolik dokumentů ztratí, když dojde k agregaci. V tomto konkrétním případě je to snadné, protože dvě odlišná hodnocení od stejného uživatele vždy odpovídají dvěma odlišným příspěvkům, takže se nemusíme obtěžovat nastavením factor a incremental_factor, protože agregační fáze nikdy nic nedělá. Stejně tak nezáleží ani na skóre. Pokud potřebujete poskytnout přesný počet celkového počtu výsledků, stačí nastavit factor dostatečně velký, aby první zametání elasticsearch dělá podřízených dokumentů najde všechny z nich. Pokud víte, že uživatel má na svém seznamu 500 hodnocených položek a žádáte o prvních 10 položek, pak by měl stačit faktor 50. Faktor musí být pouze horní hranice-nemusíte přesně vědět, kolik položek má uživatel na svém seznamu (což by mohlo být nepříjemné pracovat bez samostatného elastického vyhledávacího dotazu, pokud uživatel hledá konkrétní podmnožinu svých hodnocení).

co dostanete po tom všem toto je seznam nadřazených dokumentů (příspěvků) seřazených podle skóre dotazu podřízených dokumentů (hodnocení). K dosažení původního cíle třídění příspěvků na základě atributů podřízených dokumentů stačí zajistit, aby toto skóre dotazu mělo správnou hodnotu. Například nechte top_children dotaz zabalit dotaz custom_score , abyste měli kontrolu nad tím, jaké je skóre pro každé dítě.

se stejnými dokumenty v indexu tento dotaz vrací příspěvky, které uživatel 1234 ohodnotil, seřazené podle jejich hodnocení:

spustíme dotaz top_children, takže první věc, kterou musíme udělat, je říct, jaký je typ dětí, které zvažujeme (hodnocení). Poté poskytneme dotaz, který tyto děti najde. Jedná se o dotaz custom_score, který zabalí dotaz filtered. Dotaz filtered zajišťuje, že najdeme pouze hodnocení daná uživatelem, o který nás zajímá, a prvek script pak způsobí, že skóre dokumentu o hodnocení bude hodnoceno samo, takže naše příspěvky budou seřazeny podle hodnocení. Funkce s zpětnými lomítky je pouze proto, že se snažím zahrnout doslovný jediný citát do řetězce přátelského ke skořápce ohraničeného jednoduchými uvozovkami – skutečný json, který posíláme, má právě "script": "doc.value".

Ruby fun

bohužel knihovna pneumatik v tuto chvíli nepodporuje žádnou z těchto zábavných věcí – je tu trochu moratorium na tento druh funkce, protože v tuto chvíli každý malý typ dotazu a možnost končí samostatnými metodami rozptýlenými po celé pneumatice, což se správci pochopitelně nelíbí. Můžete to trochu nabourat.

pneumatika neumožňuje nastavit nadřazené id dokumentu při indexování. To je jednoduché přidat a je to jen zdrženo výše uvedeným moratoriem. Moje vidlice přidává tuto schopnost. S tím skončíte s

další bit neštěstí je, že auto index vytvoření pneumatiky předpokládá jeden typ na index, ale pro vztah rodič / dítě existovat oba typy musí být ve stejném indexu. Nakonec jsem udělal něco takového, abych vytvořil své indexy.

což není tak krásné, ale dostane práci.

nakonec musíte skutečně udělat dotaz. V nepřítomnosti top_children ve skutečnosti je součástí tire api můžete fudge to jako tak

Tento trochu nepříjemnosti buduje dotaz jako hash a pak strčí do pneumatiky, zatímco to vypadá na druhou stranu. Je zřejmé, že jej můžete strukturovat tak, aby bylo snadné přidat do Vyhledávání další podmínky (ať už na příspěvku nebo na hodnocení). Můžete také vytvořit json ručně a použít Post.search :payload => my_json (existuje chyba s volbou payload, která se střetává s rozšířením loggeru tire-contrib)

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.