ugrás a tartalomhoz

MongoDB - hogyan kell/érdemes 'join'-olni

danmail · 2013. Júl. 26. (P), 13.14
Sziasztok,

Ezzel kapcsolatban kezdtem elásni magam a Mongoba.
http://weblabor.hu/forumok/temak/118636

Azt nem értem még, hogyan lehet megvalósítani a dokumentumok összekapcsolását egy find-on belül.

Tegyük fel, hogy vannak a tulajdonságok. 1-1 tulajdonság a property collection-ben 1-1 doc.
Van az item collection, amiben vannak a tételek és minden tételnek van egy 'properties' tulajdonsága. Ebbe van felsorolva a property collection néháy dokumentumának az id-ja.

Hogy érem el, hogy ha lekérdezek egy item-et, akkor a properties-ben ne a property-id-kat lássam hanem magát a property-t.

Ha lekérek mondjuk ezer item-et és a bejáró ciklusba egyessével lekérdezgetem a property-ket az itemhez tartozó property_id-val akkor az elég sok find lesz. Feltételezem nem ez a legoptimálisabb.
 
1

link

razielanarki · 2013. Júl. 26. (P), 16.51
nemrég volt erről/hasonló témáról egy jó cikk a phpmasteren:

Modeling Data Relationships in MongoDB
6

Nézegetem nézegetem, de nem

danmail · 2013. Júl. 26. (P), 23.41
Nézegetem nézegetem, de nem látok benne nekem való példát.
Sajnos az angolom nem olyan erős, hogy végigolvassam :)
2

Nem kell/érdemes joinolni

MadBence · 2013. Júl. 26. (P), 18.41
Nem kell/érdemes joinolni (ebben az esetben). A MongoDB nem relációs adatbázis, az ilyen problémákat denormalizálással lehet megoldani: (properties kollekció nem kell, marad az items)

{
  "name": "quux",
  ...
  "properties": [
    "foo": "bar",
    "baz": 42,
    "qux": {
      "corge": "grault"
    },
    "garply": ["waldo", 3.14],
    ...
  ]
}
Azaz minden tulajdonságot szépen helyben kifejtesz (hiszen nem köti meg a kezedet a relációs adatbázisokban megszokott relációs séma). Igen, ez redundanciát, és a szokásos módosítási anomáliák megjelenését eredményezi. Cserébe gyorsan elő tudod rántani.
4

Elég nehéz így gondolkozni

danmail · 2013. Júl. 26. (P), 23.31
Elég nehéz így gondolkozni sql után.
És hogy oldod meg ha a 'foo'-t 'foo2'-re szeretnéd átnevezni minden itemnél?
Egyszerűen végig kell futtatni az összes item doksin az átnevezést? És ha az egyik valami oknál fogva hibásan neveződik át, akkor már sosem lehet azonosítani többé!?
7

És az gáz ha elteszem mellé

danmail · 2013. Júl. 26. (P), 23.49
És az gáz ha elteszem mellé az azonosítóját is? :)
{  
   "name": "quux",  
   "properties": [  
       {
          "id" : 123
          "name" : "foo"
       },
       {
          "id" : 124
          "name" : "bar"
       }
   ]  
}

így már nem a neve alapján kell keresnem hanem id alapján is tudom. Így eltudom képzelni, hogy használható legyen.
Szerintetek?
9

Miért kell neki azonosító?

MadBence · 2013. Júl. 27. (Szo), 00.12
Miért kell neki azonosító? Legyen egyedi a tulajdonságnév, és készen is van.

És hogy oldod meg ha a 'foo'-t 'foo2'-re szeretnéd átnevezni minden itemnél?
Egyszerűen végig kell futtatni az összes item doksin az átnevezést? És ha az egyik valami oknál fogva hibásan neveződik át, akkor már sosem lehet azonosítani többé!?
Pontosan (ez a módosítási anomália). Ha korrumpálódik az adatbázis (ami amúgy bármelyik megoldásnál előfordulhat), így jártál. Az $isolate viszont "atomi" műveletté teszi a frissítést, azaz vagy sikerül, vagy nem, így nem fordulhat elő, hogy "félig" frissül az adatbázis.

Másik lehetőség a 2PC.
11

Azért tennék be azonosítót,

danmail · 2013. Júl. 27. (Szo), 10.11
Azért tennék be azonosítót, mert az sosem változik és mondjuk a tömeges átnevezésnél abból biztonságosan megtalálom a tulajdonságot akkor is ha a neve valami oknál fogva megsérült.

Ez az isolate jófélének tűnik, bár úgy képzelem el mint egy kötegelt update-t. Vagy nem jól látom? Ha igen, akkor meg a lockolás "sokáig" is tarthat. Nem?
3

Úgy hogy beágyazod a

janez · 2013. Júl. 26. (P), 20.00
Úgy hogy beágyazod a dokumentumodba, mivel nincs megkötve a kezed ellenben a relációs sémával.

De amúgy (nagy mennyiségű adat esetén) rendelkezésedre áll a MongoDB Ref.

Itt lehetőséged van össze kapcsolni különböző adatokat "idegen kulcs" alapján. A probléma ezzel annyi, hogy a MongoDB-hez használt driver-nek ezt támogatnia kell.

Ha ez nincs akkor marad az, hogy te magad össze párosítod az adatokat, kézzel több lekérdezésen keresztül. Pl.: Így teszt a MongooseJS (NodeJS) populate funkciója is.
5

MongodDB Ref-et néztem és

danmail · 2013. Júl. 26. (P), 23.33
MongodDB Ref-et néztem és mivel php drivere támogatja próbálgattam is. De nem sikerült megértenem, hogy ennek a használatával hogyan kapom vissza az item doksit úgy ahogy szeretném.
8

Ez sem igazi join, a DBRef

MadBence · 2013. Júl. 26. (P), 23.50
Ez sem igazi join, a DBRef ugyanolyan mező, mint a többi, a driver annyit segít, hogy helyetted elvégzi az extra lekérdezéseket a hivatkozások feloldásához (tehát ugyanott vagy, ahonnan indultál).
10

Nem tudom mennyire van

janez · 2013. Júl. 27. (Szo), 01.41
Nem tudom mennyire van megkötve a kezed, de szerintem jobban járnál valami ODM-el ami egy kicsit sémába önti neked az egészet. Ezek többsége kínál neked több megoldást a problémádra.

Pl.: PHP-hez a mandango-t vagy a Doctrine próbáld ki.

Bár az előbbinek jobb a teljesítmény tesztje.
A dokumentációból:
mandango - Relation Mapping
mandango - Reference Mapping

szerk.:
Egyet kihagytam. A Morph-ot.
Morph - Relationships
12

Doctrine-t használok és

danmail · 2013. Júl. 27. (Szo), 10.14
Doctrine-t használok és tökéletesen meg is felel nekem, de szeretném is tudni, hogy mi zajlik a háttérbe. Érteni akarom a MongoDB-t
13

Doctrine-t használok és

janez · 2013. Júl. 27. (Szo), 15.06
Doctrine-t használok és tökéletesen meg is felel nekem, de szeretném is tudni, hogy mi zajlik a háttérbe. Érteni akarom a MongoDB-t

Persze értem én. Én is úgy gondoltam. :)

A lényeg, hogy két irányba mehetsz.
1. Növeled a redundanciát, ezzel növekszenek a módosítási anomáliák, de csökken a lekérdezéseid száma.
Pl.: van két kollekciód. felhasználók és a bejegyzések. Ha a bejegyzéseknél sűrűn kell megmutatni azon felhasználó nevét aki létrehozta, akkor megteheted hogy az ID mellé elrakod a nevét is. Így a megjelenítéskor megspórolhatsz egy lekérdezést. Viszont ha a név módosul akkor nem csak a felhasználók kollekciót kell frissíteni, hanem a bejegyzésekét is.

2. Az hogy az relációs sémához hasonlóan idegen kulcsot tárolsz. Amit akkor érdemes ha nagyon eltérnek az adatok, mint a felhasználó és a bejegyzés. Ilyenkor mindig kell még egy lekérdezés. Ilyenek mint a hozzászólások a bejegyzéshez ezek elférnek még a bejegyzések dokumentumban.

Ilyen esetekben a megoldást a feladat választja, mint mindig. Annyival jobb, hogy van miből választani. Itt vannak a lehetőségek: MongoDB data-modeling.

Egy megjegyzés a mongodb-ről. Mivel dokumentum orientált, így az SQL-hez hasonló aggregációs feladatok elvégzése is nagyon nehézkes. Van rá egy nagyon jó keretrendszer a mongo-n belül. De itt különösen érvényes az a szabály, hogy amit csak lehet azt érdemes elő aggregálni.