Tentokrát jsme pro Vás připravili nezávislou knihovnu, která umí sestavit dotaz do ElasticSearch. ES je primárně určena ke čtení a selektování ve velkých objemech dat. Narozdíl od relačních databází jsou zde data uložena v co nejvíce denormalizované formě. To s sebou samozřejmě nese režii při ukládání a aktualizaci záznamů, které obsahují duplicity. To znamená, že se nepoužívají žádné joiny a podobné vychytávky relačních databází, ale každý záznam obsahuje vše již předpřipravené. To naopak umožňuje nesrovnatelnou rychlost čtení na základě pravidel.

Dotaz do ES se staví odlišně, než u SQL databází a nejefektivnější cesta, jakou si v aplikaci udržet pořádek, je využít mezivrstvy, která simuluje stejný přístup, jako u relačních databází a následně dotaz převede do ES request. My využíváme ZendFramework2, takže jsme reflektovali Zend-Db.

Když sestavujeme dotaz do databáze, vypadá téměř stejně, jako když se dotazujeme do ES. Můžete tak používat mezivrstvu jako mapper, který zvolí typ úložiště a nestaráte se o nic více. Pro zvolené úložiště se dotaz správně vytvoří a pošle.

Zend-Db PredicateSet:

<?php
$_predicate_set = new Zend\Db\Sql\Predicate\PredicateSet();
$_predicate_set->nest()->equalTo('name', 'Martin')->or->equalTo('name', 'Tomáš')->unnest()->equalTo('removed', 0)

ElasticSearchPredicate

<?php
$_client = new ElasticSearchPredicate\Client();
$_search = $_client->search('<index>', '<type>');
$_search->nest()->equalTo('name', 'Martin')->or->equalTo('name', 'Tomáš')->unnest()->equalTo('removed', 0)

se přeloží na

<?php
[
	'index' => '<index>',
	'type'  => '<type>',
	'body'  => [
		'query' => [
			'bool' => [
				'must' => [
					[
						'bool' => [
							'should' => [
								[
									'term' => [
										'name' => 'Martin',
									],
								],
								[
									'term' => [
										'name' => 'Tomáš',
									],
								],
							],
						],
					],
					[
						'term' => [
							'removed' => 0,
						],
					],
				],
			],
		],
	],
];

API má samozřejmě i další nezbytné funkce, jako je limit a offset pro stránkování, apod.

Podporujeme samozřejmě i nested objects, které se v indexu definují pomocí mappings. Slouží to k vyhledávání v property, ve které je pole dalších objektů. Bez nested mappings nelze v takovém poli vyhledávat. Nested type zaručí, že vyhledávání nějaké sady predikátů se aplikuje na každý objekt v poli zvlášť.

<?php
$_search->nested('NestedPropery')->Term('NestedPropery.name', 'martin')->Term('NestedPropery.resolved', 0)->unnest()

Zdrojové kódy ke stažení: ZDE

Přidejte se / Let’s contribute