Skip to content

Commit

Permalink
Adding more objects (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
CodeDuck42 authored Mar 20, 2021
1 parent b4f315f commit d4cc557
Show file tree
Hide file tree
Showing 14 changed files with 345 additions and 60 deletions.
58 changes: 31 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,48 +32,52 @@ All issues should go to the [issue tracker from github](https://github.com/CodeD
~~~php
use CodeDuck\Elasticsearch\Action\Delete;use CodeDuck\Elasticsearch\Action\Index;
use CodeDuck\Elasticsearch\Action\Query;use CodeDuck\Elasticsearch\Client;
use Symfony\Component\HttpClient\HttpClient;
use CodeDuck\Elasticsearch\Document;use CodeDuck\Elasticsearch\Identifier;use Symfony\Component\HttpClient\HttpClient;

$index = 'my-index';
$type = '_doc'; // default value
$id1 = new Identifier('my-index', 'ID-123', '_doc');
$id2 = new Identifier('my-index', 'ID-234', '_doc');
$id3 = new Identifier('my-index', 'ID-341', '_doc');

$id1 = 'ID-123';
$id2 = 'ID-234';
$id3 = 'ID-341';

$document1 = ['name' => 'foo', 'foo' => 12345];
$document2 = ['name' => 'bar', 'foo' => 12345];
$document3 = ['name' => 'foobar', 'foo' => 12345];
$document1 = new Document($id1, ['name' => 'foo', 'foo' => 12345]);
$document2 = new Document($id2, ['name' => 'bar', 'foo' => 12345]);
$document3 = new Document($id3, ['name' => 'foobar', 'foo' => 12345]);

$client = new Client(HttpClient::create(), 'http://127.0.0.1:9200');

// index one document
$client->action(new Index($index, $id1, $document1));
$client->action(new Index($document1));

// bulk index
$client->bulkAction([
new Index($index, $id1, $document1),
new Index($index, $id2, $document2),
new Index($index, $id3, $document3),
new Index($document1),
new Index($document2),
new Index($document3),
]);

echo json_encode(
$client->query(
new Query(['query' => ['term' => ['name' => 'foobar']]], $index)
),
JSON_THROW_ON_ERROR
$result = $client->query(
new Query(['query' => ['term' => ['name' => 'foobar']]], 'my-index')
);

echo sprintf(
'It took %f ms to query %d documents, the highest score was %f' . PHP_EOL,
$result->getTook(),
$result->getCount(),
$result->getMaxScore()
);

foreach ($result->getDocuments() as $document) {
echo sprintf(
'Score: %f, Json: %s' . PHP_EOL,
$document->getScore(),
json_encode($document->getSource(), JSON_THROW_ON_ERROR)
);
}

// bulk delete
$client->bulkAction([
new Delete($index, $id1),
new Delete($index, $id2),
new Delete($index, $id3),
new Delete($id1),
new Delete($id2),
new Delete($id3),
]);

~~~

## Roadmap

- Simplified query result parser to provide easier access
- DSL builder
22 changes: 12 additions & 10 deletions src/Action/Delete.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,29 @@

namespace CodeDuck\Elasticsearch\Action;

use CodeDuck\Elasticsearch\Identifier;

/**
* @psalm-immutable
*/
final class Delete implements ActionInterface
{
private array $action;
private Identifier $identifier;

public function __construct(string $index, string $id, string $type = '_doc')
public function __construct(Identifier $identifier)
{
$this->action = [
'delete' => [
'_id' => $id,
'_type' => $type,
'_index' => $index,
],
];
$this->identifier = $identifier;
}

public function jsonSerialize(): array
{
return $this->action;
return [
'delete' => [
'_id' => $this->identifier->getId(),
'_type' => $this->identifier->getType(),
'_index' => $this->identifier->getIndex(),
],
];
}

public function getDocument(): ?array
Expand Down
27 changes: 14 additions & 13 deletions src/Action/Index.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,35 @@

namespace CodeDuck\Elasticsearch\Action;

use CodeDuck\Elasticsearch\Document;

/**
* @psalm-immutable
*/
final class Index implements ActionInterface
{
private array $action;
private array $document;
private Document $document;

public function __construct(string $index, string $id, array $document, string $type = '_doc')
public function __construct(Document $document)
{
$this->action = [
'index' => [
'_id' => $id,
'_type' => $type,
'_index' => $index,
],
];

$this->document = $document;
}

public function jsonSerialize(): array
{
return $this->action;
$identifier = $this->document->getIdentifier();

return [
'index' => [
'_id' => $identifier->getId(),
'_type' => $identifier->getType(),
'_index' => $identifier->getIndex(),
],
];
}

public function getDocument(): ?array
{
return $this->document;
return $this->document->getSource();
}
}
6 changes: 4 additions & 2 deletions src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,11 @@ public function bulkAction(array $actions): void
$this->request('POST', '/_bulk', ['body' => $request, 'headers' => ['Content-Type' => 'application/x-ndjson']]);
}

public function query(Query $query): array
public function query(Query $query): QueryResult
{
return $this->request('GET', sprintf('/%s/_search', $query->getIndex()), ['json' => $query]);
return QueryResult::fromArray(
$this->request('GET', sprintf('/%s/_search', $query->getIndex()), ['json' => $query])
);
}

private function request(string $method, string $path, array $options): array
Expand Down
46 changes: 46 additions & 0 deletions src/Document.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace CodeDuck\Elasticsearch;

/**
* @psalm-immutable
*/
final class Document
{
private Identifier $identifier;
private array $source;
private float $score;

public function __construct(Identifier $identifier, array $source, float $score = 0.0)
{
$this->identifier = $identifier;
$this->source = $source;
$this->score = $score;
}

public static function fromArray(array $result): self
{
return new self(
Identifier::fromArray($result),
isset($result['_source']) && is_array($result['_source']) ? $result['_source'] : [],
isset($result['_score']) && is_float($result['_score']) ? $result['_score'] : 0.0
);
}

public function getSource(): array
{
return $this->source;
}

public function getScore(): float
{
return $this->score;
}

public function getIdentifier(): Identifier
{
return $this->identifier;
}
}
46 changes: 46 additions & 0 deletions src/Identifier.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace CodeDuck\Elasticsearch;

/**
* @psalm-immutable
*/
final class Identifier
{
private string $index;
private string $id;
private string $type;

public function __construct(string $index, string $id, string $type = '_doc')
{
$this->index = $index;
$this->id = $id;
$this->type = $type;
}

public static function fromArray(array $result): self
{
return new self(
isset($result['_index']) && is_string($result['_index']) ? $result['_index'] : '',
isset($result['_id']) && is_string($result['_id']) ? $result['_id'] : '',
isset($result['_type']) && is_string($result['_type']) ? $result['_type'] : '_doc',
);
}

public function getIndex(): string
{
return $this->index;
}

public function getId(): string
{
return $this->id;
}

public function getType(): string
{
return $this->type;
}
}
70 changes: 70 additions & 0 deletions src/QueryResult.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

declare(strict_types=1);

namespace CodeDuck\Elasticsearch;

/**
* @psalm-immutable
*/
final class QueryResult
{
/** @var Document[] */
private array $documents = [];
private int $took;
private float $maxScore;

/**
* @param Document[] $documents
*/
public function __construct(array $documents, int $took, float $maxScore)
{
$this->documents = $documents;
$this->took = $took;
$this->maxScore = $maxScore;
}

public static function fromArray(array $result): self
{
$documents = [];

/** @psalm-suppress MixedAssignment */
if (isset($result['hits']['hits']) && is_array($result['hits']['hits'])) {
foreach ($result['hits']['hits'] as $documentArray) {
/** @psalm-suppress MixedArgument */
$documents[] = Document::fromArray($documentArray);
}
}

return new self(
$documents,
isset($result['took']) && is_int($result['took']) ? $result['took'] : 0,
isset($result['hits']['max_score']) && is_float($result['hits']['max_score'])
? $result['hits']['max_score']
: 0.0
);
}

/**
* @return Document[]
*/
public function getDocuments(): array
{
return $this->documents;
}

public function getCount(): int
{
return count($this->documents);
}

public function getTook(): int
{
return $this->took;
}

public function getMaxScore(): float
{
return $this->maxScore;
}
}
7 changes: 4 additions & 3 deletions tests/integration/ClientIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ public function testQuery(): void
$client = new Client(HttpClient::create(), 'http://localhost:9200');
$client->bulkAction(
[
new Index('test-index', '11111', ['name' => 'example']),
new Index('test-index', '22222', ['name' => 'banana']),
new Index(new Document(new Identifier('test-index', '11111'), ['name' => 'example'])),
new Index(new Document(new Identifier('test-index', '22222'), ['name' => 'banana'])),
]
);

Expand All @@ -26,6 +26,7 @@ public function testQuery(): void
$action = new Query(['query' => ['term' => ['name' => 'banana']]], 'test-index');
$result = $client->query($action);

self::assertEquals(['name' => 'banana'], $result['hits']['hits'][0]['_source']);
self::assertEquals(1, $result->getCount());
self::assertEquals(['name' => 'banana'], $result->getDocuments()[0]->getSource());
}
}
3 changes: 2 additions & 1 deletion tests/unit/Action/DeleteTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace CodeDuck\Elasticsearch\Action;

use CodeDuck\Elasticsearch\Identifier;
use PHPUnit\Framework\TestCase;

/**
Expand All @@ -13,7 +14,7 @@ class DeleteTest extends TestCase
{
public function test(): void
{
$action = new Delete('index', 'ABC123', 'document');
$action = new Delete(new Identifier('index', 'ABC123', 'document'));

self::assertEquals(
[
Expand Down
Loading

0 comments on commit d4cc557

Please sign in to comment.