diff --git a/src/Query/Builder.php b/src/Query/Builder.php index 62b977b..a7e7eb4 100644 --- a/src/Query/Builder.php +++ b/src/Query/Builder.php @@ -343,6 +343,16 @@ public function aggregations(): Aggregation return $this->aggregations; } + /** + * Return the Dsl Query object. + * + * @return \AviationCode\Elasticsearch\Query\Dsl\Query + */ + public function query(): Query + { + return $this->query; + } + /** * Perform a raw elastic query. * @@ -378,6 +388,16 @@ public function get() ], $this->model->getIndexName(), ['typed_keys' => true]), $this->model); } + public function count(): int + { + return (int) ($this->getClient()->count( + [ + 'index' => $this->model->getIndexName(), + 'body' => array_filter(['query' => $this->query->toArray()]), + ] + )['count']); + } + /** * Force a clone of the underlying query builder when cloning. * diff --git a/tests/Feature/CountTest.php b/tests/Feature/CountTest.php new file mode 100644 index 0000000..823624d --- /dev/null +++ b/tests/Feature/CountTest.php @@ -0,0 +1,111 @@ +app->instance('elasticsearch.client', $this->client = \Mockery::mock(Client::class)); + } + + /** @test */ + public function it_can_count_the_documents_without_filtering() + { + $this->client + ->shouldReceive('count') + ->with(['index' => 'article', 'body' => []]) + ->andReturn( + [ + 'count' => 122, + '_shards' => [ + 'total' => 1, + 'successful' => 1, + 'skipped' => 0, + 'failed' => 0, + ], + ] + ); + + $this->assertSame(122, $this->elastic->query(Article::class)->count()); + } + + /** @test */ + public function it_can_count_the_documents_without_an_eloquent_model() + { + $this->client + ->shouldReceive('count') + ->with(['index' => 'article', 'body' => []]) + ->andReturn( + [ + 'count' => 6, + '_shards' => [ + 'total' => 1, + 'successful' => 1, + 'skipped' => 0, + 'failed' => 0, + ], + ] + ); + + $this->assertSame(6, $this->elastic->query('article')->count()); + } + + /** @test */ + public function it_can_count_the_matching_documents_with_filter() + { + $this->client + ->shouldReceive('count') + ->with( + [ + 'index' => 'article', + 'body' => [ + 'query' => [ + 'bool' => [ + 'must' => [ + [ + 'exists' => [ + 'field' => 'published_at', + ], + ], + ], + ], + ], + ], + ] + ) + ->andReturn( + [ + 'count' => 12, + '_shards' => [ + 'total' => 1, + 'successful' => 1, + 'skipped' => 0, + 'failed' => 0, + ], + ] + ); + + $this->assertSame( + 12, + $this->elastic + ->query('article') + ->must( + function (Must $must) { + $must->exists('published_at'); + } + ) + ->count() + ); + } +}