Skip to content

Commit 2fb6391

Browse files
authored
Merge pull request #643 from einorler/issue40
Implemented multi get API
2 parents 3c30fd9 + 09eb09f commit 2fb6391

File tree

3 files changed

+72
-0
lines changed

3 files changed

+72
-0
lines changed

Resources/doc/find_functions.md

+14
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,20 @@ $content = $repo->find(1); // 5 is the document _uid in the elasticsearch.
1919

2020
> All `find` methods return an object. If you want to get raw result use `execute($search, Result::RESULTS_RAW)`.
2121
22+
## Find multiple documents by ID
23+
24+
If multiple documents need to be found by their IDs, `findByIds()` method can be used. It accepts an array of document IDs
25+
and returns `DocumentIterator` with found documents:
26+
27+
```php
28+
29+
$documents = $repo->findByIds(['26', '8', '11']);
30+
31+
```
32+
33+
For this functionality the `Repository` uses
34+
[elasticsearch multi get API](https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-multi-get.html).
35+
2236
## Find by field
2337

2438
Find by field uses [query_string query](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html) to fetch results by a specified field value.

Service/Repository.php

+36
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,42 @@ public function find($id, $routing = null)
9292
return $this->manager->find($this->type, $id, $routing);
9393
}
9494

95+
/**
96+
* Returns documents by a set of ids
97+
*
98+
* @param array $ids
99+
*
100+
* @return DocumentIterator The objects.
101+
*/
102+
public function findByIds(array $ids)
103+
{
104+
$args = [];
105+
$manager = $this->getManager();
106+
$args['body']['docs'] = [];
107+
$args['index'] = $manager->getIndexName();
108+
$args['type'] = $this->getType();
109+
110+
foreach ($ids as $id) {
111+
$args['body']['docs'][] = [
112+
'_id' => $id
113+
];
114+
}
115+
116+
$mgetResponse = $manager->getClient()->mget($args);
117+
118+
$return = [];
119+
120+
foreach ($mgetResponse['docs'] as $item) {
121+
if ($item['found']) {
122+
$return['hits']['hits'][] = $item;
123+
}
124+
}
125+
126+
$return['hits']['total'] = count($return['hits']['hits']);
127+
128+
return new DocumentIterator($return, $manager);
129+
}
130+
95131
/**
96132
* Finds documents by a set of criteria.
97133
*

Tests/Functional/Service/RepositoryTest.php

+22
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace ONGR\ElasticsearchBundle\Tests\Functional;
1313

14+
use ONGR\ElasticsearchBundle\Result\DocumentIterator;
1415
use ONGR\ElasticsearchBundle\Tests\app\fixture\Acme\BarBundle\Document\Product;
1516
use ONGR\ElasticsearchDSL\Query\MatchAllQuery;
1617
use ONGR\ElasticsearchDSL\Query\PrefixQuery;
@@ -491,4 +492,25 @@ public function testCountApiRawResponse()
491492

492493
$this->assertEquals($shards, $count['_shards']);
493494
}
495+
496+
/**
497+
* Tests mget method
498+
*/
499+
public function testFindByIds()
500+
{
501+
$manager = $this->getManager('default');
502+
$repository = $manager->getRepository('AcmeBarBundle:Product');
503+
$results = $repository->findByIds([1, 2, 5]);
504+
505+
$this->assertInstanceOf(DocumentIterator::class, $results);
506+
$this->assertEquals(2, count($results));
507+
$i = 0;
508+
foreach ($results as $product) {
509+
$this->assertInstanceOf(Product::class, $product);
510+
$this->assertEquals(
511+
$this->getDataArray()['default']['product'][$i++]['price'],
512+
$product->getPrice()
513+
);
514+
}
515+
}
494516
}

0 commit comments

Comments
 (0)