diff --git a/changes.txt b/changes.txt index 2277061cb6..4e5081703b 100755 --- a/changes.txt +++ b/changes.txt @@ -1,10 +1,12 @@ CHANGES +2014-06-30 +- Add Reverse Nested aggregation (http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-bucket-reverse-nested-aggregation.html). 2014-06-14 - Release v1.2.1.0 - Removed the requirement to set arguments filter and/or query in Filtered, according to the documentation: http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-filtered-query.html #616 - + 2014-06-13 - Stop ClientTest->testDeleteIdsIdxStringTypeString from failing 1/3 of the time #634 - Stop ScanAndScrollTest->testQuerySizeOverride from failing frequently for no reason #635 diff --git a/lib/Elastica/Aggregation/ReverseNested.php b/lib/Elastica/Aggregation/ReverseNested.php new file mode 100644 index 0000000000..d4056f130c --- /dev/null +++ b/lib/Elastica/Aggregation/ReverseNested.php @@ -0,0 +1,50 @@ +setPath($path); + } + } + + /** + * Set the nested path for this aggregation + * + * @param string $path + * @return ReverseNested + */ + public function setPath($path) + { + return $this->setParam("path", $path); + } + + /** + * {@inheritDoc} + */ + public function toArray() + { + $array = parent::toArray(); + + // ensure we have an object for the reverse_nested key. + // if we don't have a path, then this would otherwise get encoded as an empty array, which is invalid. + $array['reverse_nested'] = (object)$array['reverse_nested']; + + return $array; + } +} diff --git a/test/lib/Elastica/Test/Aggregation/ReverseNestedTest.php b/test/lib/Elastica/Test/Aggregation/ReverseNestedTest.php new file mode 100644 index 0000000000..215dac63fd --- /dev/null +++ b/test/lib/Elastica/Test/Aggregation/ReverseNestedTest.php @@ -0,0 +1,124 @@ +_index = $this->_createIndex("nested"); + $mapping = new Mapping(); + $mapping->setProperties(array( + "comments" => array( + "type" => "nested", + "properties" => array( + "name" => array("type" => "string"), + "body" => array("type" => "string") + ) + ) + )); + $type = $this->_index->getType("test"); + $type->setMapping($mapping); + $docs = array( + new Document("1", array( + "comments" => array( + array( + "name" => "bob", + "body" => "this is bobs comment", + ), + array( + "name" => "john", + "body" => "this is johns comment", + ), + ), + "tags" => array("foo", "bar"), + )), + new Document("2", array( + "comments" => array( + array( + "name" => "bob", + "body" => "this is another comment from bob", + ), + array( + "name" => "susan", + "body" => "this is susans comment", + ), + ), + "tags" => array("foo", "baz"), + )) + ); + $type->addDocuments($docs); + $this->_index->refresh(); + } + + public function testPathNotSetIfNull() + { + $agg = new ReverseNested('nested'); + $this->assertFalse($agg->hasParam('path')); + } + + public function testPathSetIfNotNull() + { + $agg = new ReverseNested('nested', 'some_field'); + $this->assertEquals('some_field', $agg->getParam('path')); + } + + public function testReverseNestedAggregation() + { + $agg = new Nested("comments", "comments"); + $names = new Terms("name"); + $names->setField("comments.name"); + + $tags = new Terms("tags"); + $tags->setField("tags"); + + $reverseNested = new ReverseNested("main"); + $reverseNested->addAggregation($tags); + + $names->addAggregation($reverseNested); + + $agg->addAggregation($names); + + $query = new Query(); + $query->addAggregation($agg); + $results = $this->_index->search($query)->getAggregation("comments"); + + $this->assertArrayHasKey('name', $results); + $nameResults = $results['name']; + + $this->assertCount(3, $nameResults['buckets']); + + // bob + $this->assertEquals('bob', $nameResults['buckets'][0]['key']); + $tags = array( + array('key' => 'foo', 'doc_count' => 2), + array('key' => 'bar', 'doc_count' => 1), + array('key' => 'baz', 'doc_count' => 1), + ); + $this->assertEquals($tags, $nameResults['buckets'][0]['main']['tags']['buckets']); + + // john + $this->assertEquals('john', $nameResults['buckets'][1]['key']); + $tags = array( + array('key' => 'bar', 'doc_count' => 1), + array('key' => 'foo', 'doc_count' => 1), + ); + $this->assertEquals($tags, $nameResults['buckets'][1]['main']['tags']['buckets']); + + // susan + $this->assertEquals('susan', $nameResults['buckets'][2]['key']); + $tags = array( + array('key' => 'baz', 'doc_count' => 1), + array('key' => 'foo', 'doc_count' => 1), + ); + $this->assertEquals($tags, $nameResults['buckets'][2]['main']['tags']['buckets']); + } +}