-
Notifications
You must be signed in to change notification settings - Fork 3
Added Index implementation #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
poratuk
wants to merge
9
commits into
phonetworks:master
Choose a base branch
from
poratuk:index-implementation
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 6 commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
c450507
Added Index implementation
poratuk 7dffddd
Rename indexes to index
poratuk 0967355
Added test.
poratuk 89f3bb8
Inidexing working. Tests passed
poratuk 4fa206e
Changed Elasticsearch indexing to types.
poratuk c48e427
Some small changes on create/remove indexes
poratuk 3ed1835
Fixing tests to index nodes on node creating...
poratuk 3ad80c7
Removed Elasticserch adapter from microkernel
poratuk d71bb1a
Remove first errored test. Use test client for Erkasticsearch (not in…
poratuk File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,6 @@ | ||
| DATABASE_TYPE="redis" | ||
| DATABASE_URI"="redis://127.0.0.1:6379" | ||
| STORAGE_TYPE="filesystem" | ||
| STORAGE_URI="filesystem:// /tmp/pho" | ||
| STORAGE_URI="filesystem:// /tmp/pho" | ||
| INDEX_TYPE="elasticsearch" | ||
| INDEX_URI="http://localhost:9200" |
235 changes: 235 additions & 0 deletions
235
src/Pho/Kernel/Services/Index/Adapters/Elasticsearch.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,235 @@ | ||
| <?php | ||
|
|
||
| /* | ||
| * This file is part of the Pho package. | ||
| * | ||
| * (c) Emre Sokullu <emre@phonetworks.org> | ||
| * | ||
| * For the full copyright and license information, please view the LICENSE | ||
| * file that was distributed with this source code. | ||
| */ | ||
|
|
||
| namespace Pho\Kernel\Services\Index\Adapters; | ||
|
|
||
| use Pho\Kernel\Kernel; | ||
| use Pho\Kernel\Services\Index\Index; | ||
| use Pho\Kernel\Services\ServiceInterface; | ||
| use Elasticsearch\ClientBuilder; | ||
|
|
||
| /** | ||
| * File based logging. The log files specified at the kernel | ||
| * constructor level or via the *configure* function of the kernel. | ||
| * | ||
| * @author Emre Sokullu | ||
| */ | ||
| class Elasticsearch extends Index | ||
| { | ||
| private $kernel; | ||
| public $client; | ||
| private $dbname = 'phonetworks'; | ||
| private $tablename = 'phoindex'; | ||
|
|
||
| /** | ||
| * Setup function. | ||
| * Init elasticsearch connection. Run indexing on runned events | ||
| * @param Kernel $kernel Kernel of pho | ||
| * @param array $params Sended params to the index. | ||
| */ | ||
| public function __construct(Kernel $kernel, array $params = []) | ||
| { | ||
| $this->dbname = getenv('INDEX_DB')?: $this->dbname; | ||
| $this->tablename = getenv('INDEX_TABLE')?: $this->tablename; | ||
|
|
||
| $host = [$params['host'] ?: getenv('INDEX_URL') ?: 'http://127.0.0.1:9200/']; | ||
| $client = new \Elasticsearch\ClientBuilder($host); | ||
| $this->client = $client->build(); | ||
|
|
||
| $indexParams['index'] = $this->dbname; | ||
|
|
||
| if ( ! $this->client->indices()->exists($indexParams)) { | ||
| $this->client->indices()->create($indexParams); | ||
| $this->kernel->logger()->info("Created Elasticsearch index with name: %s", $this->dbname); | ||
| } | ||
|
|
||
| $kernel->on('kernel.booted_up', array($this, 'kernelBooted')); | ||
| } | ||
|
|
||
| public function kernelBooted() | ||
| { | ||
| var_dump('Kernel booted'); | ||
| $this->kernel->graph()->on('node.added', array($this, 'index')); | ||
| } | ||
|
|
||
| /** | ||
| * Bulk insert params of entity to the index | ||
| * @param string $id uuid of entity | ||
| * @param array $params array of params with key => value structure (toArray() method) | ||
| * @param array $classes classes of the current entity | ||
| */ | ||
| public function addToIndex(string $id, array $params, array $classes = []): void | ||
| { | ||
| $body = ['attr' => [], 'classes' => $classes, 'id' => $id]; | ||
| foreach ($params as $key => $value) { | ||
| $body['attr'][] = ['k' => $key, 'v' => (string)$value]; | ||
| } | ||
| $class = $this->getTypeFromClass($classes); | ||
|
|
||
| $query = $this->createQuery($class, $id, $body); | ||
| $this->client->index($query); | ||
| } | ||
|
|
||
| /** | ||
| * Updating existing entity attributes to the Indexing DB | ||
| * @param string $id uuid/id of entity | ||
| * @param array $results array of attributes with key => value structure (toArray() method) | ||
| * @param array $classes classes of the current entity | ||
| */ | ||
| public function editInIndex(string $id, array $params, array $classes = []): void | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. public? |
||
| { | ||
| //If node not founded in index - add it. | ||
| $founded = $this->searchById($id); | ||
| if ( ! empty($founded)) { | ||
| $type = $this->getTypeFromClass($founded['classes']); | ||
| $this->removeById($type, $id); | ||
| } | ||
|
|
||
| //Update document if node are exists | ||
| $body = ['attr' => [], 'classes' => $classes]; | ||
| foreach ($params as $key => $value) { | ||
| $body['attr'][] = ['k' => $key, 'v' => (string)$value]; | ||
| } | ||
|
|
||
| $params = $this->createQuery($this->getTypeFromClass($classes), $id, $body); | ||
| $this->client->index($params); | ||
| } | ||
|
|
||
| /** | ||
| * Search in indexing DB all attributes of entity by its ID | ||
| * @param string $id uuid string | ||
| * @return array array with keys id, key, value | ||
| */ | ||
| public function searchById(string $id): array | ||
| { | ||
| try { | ||
| $query = ['query' => ['match' => ['id' => $id]]]; | ||
| $params = $this->createQuery(null, null, $query); | ||
|
|
||
| $results = $this->client->search($params); | ||
| } catch (Elasticsearch\Common\Exceptions\TransportException $e) { | ||
| return false; | ||
| } catch (Elasticsearch\Common\Exceptions\Missing404Exception $e) { | ||
| return false; | ||
| } | ||
| $founded = $this->remapReturn($results); | ||
| if (isset($founded[0])) { | ||
| return $founded[0]; | ||
| } else { | ||
| return $founded; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Search in indexing DB all attributes of entity by its ID | ||
| * @param string $id uuid string | ||
| * @return array array with keys id, key, value | ||
| */ | ||
| public function removeById(string $type, string $id): array | ||
| { | ||
| $params = $this->createQuery($type, $id, false); | ||
| return $this->client->delete($params); | ||
| } | ||
|
|
||
| /** | ||
| * Search by some params | ||
| * @param string $id uuid string | ||
| * @return array array with keys id, key, value | ||
| */ | ||
| public function searchInIndex(string $value, string $key = null, array $classes = array()): array | ||
| { | ||
| $query = ['query' => ['bool' => ['must' => []]]]; | ||
| $query['query']['bool']['must'][]['match']['attr.v'] = $value; | ||
| if ( ! is_null($key)) { | ||
| $query['query']['bool']['must'][]['match']['attr.k'] = $key; | ||
| } | ||
|
|
||
| $params = $this->createQuery(implode(',', (array)$classes), null, $query); | ||
| $results = $this->client->search($params); | ||
| return $this->getIdsList($this->remapReturn($results)); | ||
| } | ||
|
|
||
| public function getTypeFromClass($classes) { | ||
| $type = 'entity'; | ||
| $class = false; | ||
|
|
||
| if (is_array($classes)) { | ||
| $class = array_shift($classes); | ||
| } | ||
|
|
||
| if (is_string($classes)) { | ||
| $class = $classes; | ||
| } | ||
|
|
||
| if ($class){ | ||
| $type = substr($class, strrpos($class, '\\') + 1); | ||
| } | ||
|
|
||
|
|
||
| return $type; | ||
| } | ||
|
|
||
| public function remapReturn(array $results) | ||
| { | ||
| $return = array(); | ||
| if (isset($results['hits']) && isset($results['hits']['hits'])) { | ||
| foreach ($results['hits']['hits'] as $founded) { | ||
| $a = [ | ||
| 'id' => $founded['_source']['id'], | ||
| 'attributes' => [], | ||
| 'classes' => $founded['_source']['classes'], | ||
| ]; | ||
| foreach ($founded['_source']['attr'] as $attribute) { | ||
| $a['attributes'][$attribute['k']] = $attribute['v']; | ||
| } | ||
| array_push($return, $a); | ||
| } | ||
| } else if (isset($results['_id']) && isset($results['_source'])) { | ||
| $return['id'] = $results['_source']['id']; | ||
| $return['classes'] = $results['_source']['classes']; | ||
| $return['type'] = $results['_type']; | ||
| foreach ($results['_source']['attr'] as $attribute) { | ||
| $return['attributes'][$attribute['k']] = $attribute['v']; | ||
| } | ||
| } | ||
| return $return; | ||
| } | ||
|
|
||
| public function getIdsList($founded): array | ||
| { | ||
| $ids = []; | ||
| foreach ($founded as $entitys) { | ||
| $ids[] = $entitys['id']; | ||
| } | ||
|
|
||
| return $ids; | ||
| } | ||
|
|
||
| public function createQuery(string $type = null, string $id = null, $where = []): array | ||
| { | ||
| $query = ['index' => $this->dbname]; | ||
| if ($type) { | ||
| $query['type'] = $type; | ||
| } | ||
|
|
||
| if ($where !== false) | ||
| { | ||
| $query['body'] = $where; | ||
| } | ||
|
|
||
| if (!is_null($id)) { | ||
| $query['id'] = $id; | ||
| } | ||
|
|
||
| return $query; | ||
| } | ||
|
|
||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| <?php | ||
|
|
||
| /* | ||
| * This file is part of the Pho package. | ||
| * | ||
| * (c) Emre Sokullu <emre@phonetworks.org> | ||
| * | ||
| * For the full copyright and license information, please view the LICENSE | ||
| * file that was distributed with this source code. | ||
| */ | ||
| namespace Pho\Kernel\Services\Index; | ||
|
|
||
| use Pho\Kernel\Kernel; | ||
| use Pho\Lib\Graph\EntityInterface; | ||
| use Pho\Kernel\Services\ServiceInterface; | ||
| use Pho\Kernel\Services\Index\Adapters; | ||
|
|
||
| /** | ||
| * Provides Index methods to the Events adapter classes. | ||
| */ | ||
| class Index implements IndexInterface, ServiceInterface | ||
| { | ||
| private $kernel; | ||
|
|
||
| public function __construct(Kernel $kernel, array $params = []) | ||
| { | ||
| $this->kernel = $kernel; | ||
| } | ||
|
|
||
| /** | ||
| * Indexes an entity. | ||
| * | ||
| * @param EntityInterface $entity An entity object; node or edge. | ||
| * @param bool $new Whether the object has just been initialized, hence never been indexed before. | ||
| * | ||
| * @return void | ||
| */ | ||
| public function index(EntityInterface $entity, bool $new = false): void | ||
| { | ||
| $classes = [get_class($entity) => get_class($entity)] + class_parents($entity); | ||
| if ($new) { | ||
| $this->addToIndex($entity->id()->toString(), $entity->attributes()->toArray(), $classes); | ||
| } else { | ||
| $this->editInIndex($entity->id()->toString(), $entity->attributes()->toArray(), $classes); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Searches through the index with given key and its value. | ||
| * | ||
| * @param string $value Value to search | ||
| * @param string $key The key to search for. Optional. | ||
| * @param array $classes The object classes to search for. Optional. | ||
| * | ||
| * @return array | ||
| */ | ||
| public function search(string $value, string $key = null, array $classes = array()): array | ||
| { | ||
| return $this->searchInIndex($value, $key, $classes); | ||
| } | ||
|
|
||
| /** | ||
| * Searches through the index with given key and its value. | ||
| * | ||
| * Returns the entity IDs as string | ||
| * | ||
| * @param string $value Value to search | ||
| * @param string $key The key to search for. Optional. | ||
| * @param array $classes The object classes to search for. Optional. | ||
| * | ||
| * @return array Entity IDs (in string format) in question | ||
| */ | ||
| public function searchFlat(string $value, string $key = "", array $classes = array()): array | ||
| { | ||
| return []; | ||
| } | ||
|
|
||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we may index edges too. event: edge.added