Space Vatican
amikor indexeli az adatokat, a világ ritkán olyan egyszerű, mint minden dokumentum létezik elszigetelten. Néha jobb, ha az összes adatot denormalizálja a gyermekdokumentumokba. Ha például könyveket modellezett, ésszerű választás lehet egy szerző mező hozzáadása a könyvekhez (még akkor is, ha a mérvadó adatforrásnak számító adatbázisban az adatok külön authors
és books
táblára vannak felosztva). Ez egyszerű, és könnyen össze lekérdezéseket mind attribútumok a könyv és a szerző nevét.
ez nem mindig praktikus – lehet, hogy túl sok adat van a szülődokumentumban ahhoz, hogy minden egyes gyermekdokumentumban lemásolják. Ha megvan a tipikus blog / megjegyzés alkalmazás, akkor nem szeretné megismételni a blogbejegyzés teljes tartalmát minden megjegyzésben,mivel ez jelentősen növelné az indexelt adatok mennyiségét. Mégis anélkül, hogy nem lehet könnyen írni lekérdezéseket találni megjegyzéseket hozzászólás megfelelő bizonyos kritériumok (más, mint csinál egy 2 lépésben a folyamat első megállapítás megfelelő hozzászólásokat, majd letölti megjegyzéseket egy bizonyos post_id
, ami gyakran nehézkes vagy lassú (vagy mindkettő)).
egy másik lehetőség a gyermekdokumentumok elhelyezése a szülődokumentumban, például az űrlap dokumentumai lehetnek
123456789101112 |
|
ennek egyik hátránya, hogy a gyermek hozzáadásához a teljes dokumentum újraindexelése szükséges. Könnyű megtalálni azokat a szerzőket, akik egy bizonyos műfajú könyveket írtak, de nehezebb megtalálni azokat a szerzőket, akiknek a penguin által kiadott tudományos-fantasztikus könyve volt.
ha az indexünk
– et tartalmaz, akkor a legnyilvánvalóbb lekérdezés
mindkét szerzőt megtalálja-nem fejezheti ki, hogy a published
és a genre
feltételeinek meg kell egyezniük ugyanazzal a könyvvel.
az ElasticSearch két dolgot kínál, amelyek segítenek ebben. Az első a beágyazott dokumentum/lekérdezés fogalma. Ez lehetővé teszi, hogy azt mondja, hogy olyan szerzőket keres, ahol legalább egy könyv megfelel mindkét kritériumnak.
először be kell állítania egy leképezést, amely azt mondja, hogy a könyvek mező be lesz ágyazva:
123456789 |
|
ha ezután ugyanazokat az adatokat illesztjük be az új indexbe, mint korábban, akkor ez a lekérdezés
itt a nested
szűrő lehetővé teszi, hogy lekérdezést futtasson a beágyazott dokumentumok (azaz a könyvek) ellen, és szűrje a szerzőket azok alapján, amelyeknek legalább egy beágyazott dokumentuma megfelel a lekérdezésnek. A path
opció megmondja, hogy a szerzők dokumentumának melyik részére vonatkozik ez a lekérdezés, majd a query
opció egy lekérdezés, amelyet ezen beágyazott dokumentumok ellen kell futtatni. Az előző lekérdezéstől eltérően ez megköveteli, hogy egy egyedi könyv mindkét követelménynek megfeleljen, így csak Alaistair Reynolds kerül visszaadásra
szülő & gyermek
a másik koncepció elasticsearch biztosítja, hogy a szülő és a gyermek közötti kapcsolat dokumentumok. Az előző példa átdolgozható a szerzőkkel szülő dokumentumokként, a könyvekkel pedig gyermekdokumentumokként.
ezúttal a szerzőket külön indexelje a könyveiktől:
majd konfigurálja a könyvtípus leképezését, és mondja ki, hogy a szülő típusa bare_author
. Ezt meg kell tennie, mielőtt bármilyen könyvet létrehozna.
12345 |
|
amikor indexelés könyvek, akkor meg kell adni az azonosítót a szülő (azaz mi a kínálat az azonosítót az egyik korábban létrehozott szerzők)
Elasticsearch biztosít has_child
szűrő, amely nem elég sok, amit mond a tin: kiválasztja azokat a szülő dokumentumokat, amelyeknek legalább egy gyermeke megfelel egy bizonyos lekérdezésnek. Ez a lekérdezés csak Alastair Reynolds-ot találja meg:
a Solr 4.0 nyilvánvalóan képes lesz csatlakozni, bár amennyire meg tudom mondani, ez bizonyos korlátozásokkal jár, különösen nem csatlakozik, ha elosztott környezetben működik. Azáltal, hogy a szülő/gyermek típusú kapcsolatokra korlátozódik, az elasticsearch megkönnyíti az életét: a gyermeket mindig ugyanabban a szilánkban indexelik, mint a szülőjét, így has_child
nem kell kellemetlen keresztszilánkot végrehajtania.
építési listák
ezt felhasználhatja a megosztott globális elemek felhasználóspecifikus listáinak modellezésére is – például ha olyan elemeket szeretne, amelyeket egy felhasználó értékelt. Ebben az esetben a gyermekdokumentumok azt a tényt képviselik, hogy egy adott felhasználó egy adott bejegyzést értékelt – ezek nem többek, mint egy user_id
, post_id
és egy értékelés: egy csatlakozási tábla a relációs adatbázis lingo-ban.
a szülő/gyermek kapcsolatok és a has_child
segítségével könnyedén megtalálhatja a felhasználó által kedvelt összes bejegyzést, miközben lehetővé teszi a felhasználók számára, hogy a bejegyzés tartalma, dátuma vagy bármely más bejegyzés attribútuma vagy a gyermek elem tulajdonságai alapján keressenek kedvenceik között. Egy elem hozzáadása a minősített elemek listájához olcsó – csak egy nagyon kicsi rating
elem indexelését igényli.
ezekkel a dokumentumokkal
ez a lekérdezés
csak “Bolívia rated 4” – et talál, mivel ez az egyetlen olyan bejegyzés, amely Bolíviát említi, amelyet az érdeklődő felhasználó több mint 3-ra értékelt. A cím legfelső szintű lekérdezése a bejegyzésekre vonatkozik, ahol a has_child
szűrőn belüli lekérdezés leírja azokat a feltételeket, amelyeknek a gyermekeknek meg kell felelniük (ebben az esetben egy adott felhasználóhoz kell tartozniuk, és legalább egy bizonyos minősítéssel kell rendelkezniük).
rendelés
amit a has_child
nem enged meg, az a gyermekek attribútumai vagy a gyermek visszatérési attribútumai alapján történő rendelés. Ha a felhasználó által értékelt bejegyzéseket az alapján szeretné megrendelni, hogy mikor értékelték őket, vagy a minősítés csökkentésével, akkor közvetlenül kereshet a bejegyzések/besorolás ellen, de érdemes néhány keresési kritériumot alkalmazni a bejegyzésekre is. Például érdemes csak egy adott témában minősített bejegyzéseket találni (továbbra is a felhasználó által megadott besorolás alapján rendel). A has_child
– tal nincs szerencséd. A beágyazott dokumentumok sem segítenek.
0.19.10-től használhatja a has_parent
szűrőt. Ez szinte pontosan ugyanúgy működik, mint a has child, de lehetővé teszi, hogy ehelyett lekérdezést adjon meg a szülőelemekkel szemben. Ez a lekérdezés az 1234-es felhasználó értékelését adja vissza, olyan bejegyzéseken, amelyek címe megegyezik a “Bolívia” – val, csökkenő pontszámrendben
ez visszaadja a minősítési objektumokat-ezután külön lekérdezéssel kell lekérnie a megfelelő bejegyzéseket.
szimulál
ha elakad egy régebbi változata elasticsearch, akkor kap a legtöbb utat ott top_children
. A dokumentáció szerint top_children
először lekérdezi a gyermekdokumentumokat, majd összesíti őket szülődokumentumokká. Példánkban ez azt jelenti, hogy az elasticsearch először megtalálja a lekérdezésünknek megfelelő minősítési dokumentumokat. Ezután minden besorolást meg fog egyezni a szülő bejegyzésével, összesítve az ismétlődő bejegyzést, ahol léteznek.
a legjobb gyerekekkel az a furcsa, hogy az elasticsearch nem tudja előre, hogy hány dokumentumot veszít el, amikor az összesítés megtörténik. Ebben az esetben könnyű, mert ugyanazon felhasználó két különböző értékelése mindig két különálló bejegyzésnek felel meg, így nem kell bajlódnunk a factor
és a incremental_factor
beállításokkal, mert az összesítési fázis soha nem tesz semmit. Hasonlóképpen, a pontszám mód sem számít. Ha pontosan meg kell adnia az eredmények teljes számát, akkor csak annyit kell beállítania, hogy a factor
elég nagy legyen ahhoz, hogy az Elasticsearch első sweepje a gyermekdokumentumokból megtalálja mindet. Ha tudod, hogy a felhasználónak 500 minősített eleme van a listáján, és az első 10 elemet kéri, akkor az 50-es tényezőnek meg kell tennie a trükköt. A tényezőnek csak felső határnak kell lennie-nem kell pontosan tudnia, hogy hány elem van a felhasználó listáján (ami kínos lehet külön rugalmas keresési lekérdezés nélkül, ha a felhasználó a minősítések egy meghatározott részhalmazát keresi).
mit kap mindezek után ez a szülői dokumentumok (hozzászólások) listája, a gyermekdokumentumok (értékelések) lekérdezési pontszáma szerint rendezve. Ahhoz, hogy elérjük az eredeti célt, hogy a bejegyzéseket a gyermekdokumentumok attribútumai alapján rendezzük, csak azt kell biztosítanunk, hogy ez a lekérdezési pontszám megfelelő értéket kapjon. Például a top_children
lekérdezés egy custom_score
lekérdezést tekerjen be, hogy Ön szabályozhassa az egyes gyermekek pontszámát.
ugyanazokkal a dokumentumokkal az indexben ez a lekérdezés visszaadja azokat a bejegyzéseket, amelyeket az 1234 felhasználó értékelt, minősítésük szerint rendezve:
top_children
lekérdezést futtatunk, tehát az első dolog, amit meg kell tennünk, hogy megmondjuk, milyen típusú gyermekeket fontolgatunk (értékelés). Ezután megadjuk a lekérdezést, amely megtalálja ezeket a gyerekeket. Ez egy custom_score
lekérdezés, amely filtered
lekérdezést csomagol. A filtered
lekérdezés biztosítja, hogy csak az érdeklődő felhasználó által megadott értékeléseket találjuk meg, majd a script
elem a minősítési dokumentum pontszámát maga minősíti, így a bejegyzéseinket besorolás szerint rendezzük. A backslashes funkiness csak azért van, mert egy szó szerinti egyetlen idézetet próbálok beilleszteni egy héjbarát karakterláncba, amelyet egyetlen idézőjelek határolnak – a tényleges json, amelyet küldünk, csak "script": "doc.value"
.
Ruby fun
sajnos a gumiabroncs – könyvtár jelenleg nem igazán támogatja ezeket a szórakoztató dolgokat-van egy kis moratórium az ilyen jellegű funkciók hozzáadására, mert jelenleg minden egyes kis lekérdezési típus és opció külön módszerek lesznek szétszórva az egész gumiabroncson, ami a karbantartónak érthető módon nem tetszik. De valahogy feltörheted.
a Tire nem teszi lehetővé a dokumentum szülőazonosítójának beállítását indexeléskor. Ezt könnyű hozzátenni, és csak a fent említett moratórium tartja fenn. A villám hozzáadja ezt a képességet. Ezzel
a következő boldogtalanság az, hogy a tire automatikus index létrehozása indexenként egy típust feltételez, de ahhoz, hogy a szülő/gyermek kapcsolat létezzen, mindkét típusnak ugyanabban az indexben kell lennie. Végül valami ilyesmit csináltam, hogy létrehozzam az indexeimet.
ami nem olyan szép, de elvégzi a munkát.
végül meg kell tennie a lekérdezést. Hiányában top_children
ténylegesen része tire api akkor Caramel ez, mint így
ez a kis kellemetlenség építi fel a lekérdezést, mint egy hash, majd lök be tire miközben néz a másik irányba. Nyilvánvalóan úgy strukturálhatja, hogy könnyű más feltételeket (akár postán, akár minősítésen) hozzáadni a kereséshez. A json-t manuálisan is felépítheti, és használhatja a Post.search :payload => my_json
– et (van egy hiba a hasznos teher opcióval, amely ütközik a tire-contrib logger kiterjesztésével)