{lang: 'hu'}

Tegnap belefutottam egy érdekes problémába a MongoDB-vel kapcsolatban: egy dokumentum property-je ugybár lehet egy másik dokumentumra mutató hivatkozás is, de vajon lehet fájlokra is mutatni így linkkel? Igen! Nekem egy felhasználó profilt kell modelleznem az adatbázisban, viszont a profilképeket nem akartam inline betenni a profil infót tartalmazó dokumentumba (egyrészt a file-okat először is Base64-el encode-olni kellene, ami elég durva méretnövekedést tud okozni, másrészt pedig egy általános keresésnél, ahol nincs megadva mely mezőkre van szükségem egészen letudja lassítani a keresést).

A profil dokumentumok szerkezete így néz ki:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
   "userId":"4e5de5348deb9f622e000215",
   "firstName":"Gabor",
   "lastName":"Szabo",
   ...,
   "pictures":{
      "profilePicture":{
         "small": GridFS Reference,
         "medium": GridFS Reference,
         "big": GridFS Reference
      },
      ...
   },
   ...
}

1. lépés: szúrjuk be a GridFS-be a kívánt profilképet

1
2
3
4
5
$m = new Mongo();
$db = $m->test_db;
$profiles = $db->profiles;
$gridFS = $db->getGridFS();
$gridFS->storeFile("profile_pic.jpg", array("metadata" => array("date" => new MongoDate())));

2. lépés: kérjük le a beszúrt objektumot (az egyszerűség kedvéért a GridFS-ben csak egy kép lesz, de természetesen a find ugyanúgy működik itt is, mint az egyéb collection-ök esetén)

1
2
3
4
5
$m = new Mongo();
$db = $m->test_db;
$profiles = $db->profiles;
$gridFS = $db->getGridFS();
$picture = $gridFS->findOne();

3. lépés: szúrjuk be a profil dokumentumot a profiles collection-be, a lekért kép-re való hivatkozással

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$doc = array(
	"userId"    => "4e5de5348deb9f622e000215",
	"firstName" => "Gabor",
	"lastName"  => "Szabo",
	...
	"pictures"  => array(
		"profilePicture" => array(
			"small"  => MongoDBRef::create($gridFS->getName(), $picture->file['_id']),
			"medium" => MongoDBRef::create($gridFS->getName(), $picture->file['_id']),
			"big"    => MongoDBRef::create($gridFS->getName(), $picture->file['_id'])
		)
	),
	...
);
 
$profiles->insert($doc);

4. lépés: kérjük le a profilban dokumentumban szereplő valamelyik képet (az egyszerűség kedvéért megint feltételezzük, hogy csak egy dokumentumunk van a collection-ben)

1
2
3
4
5
$p = $profiles->findOne();
$smallProfilePicture = MongoDBRef::get($db, $p['pictures']['profilePicture']['small']);
 
/* A fájl tényleges tartalma pedig így kapható meg */
$smallProfilePicture->getBytes();