Skip to content
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

Add parent aggregation #1616

Merged
merged 3 commits into from
Apr 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ All notable changes to this project will be documented in this file based on the

### Added

* Added `ParentAggregation` [#1616](https://github.com/ruflin/Elastica/pull/1616)

### Improvements
* Added `native_function_invocation` CS rule [#1606](https://github.com/ruflin/Elastica/pull/1606)
* Elasticsearch test version changed from 6.5.2 to 6.6.1 [#1620](https://github.com/ruflin/Elastica/pull/1620)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like a bit more changes in the changelog then there should be?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry this is my first PR, I'm still discovering how to use git in such way...
I did a rebase of my parent-agg branch onto your origin/master branch but I don't really understand what happened after (my IDE added an empty merge, I don't know why, but I definitely did a rebase). When I try to rebase again, it says that my branch is up-to-date with your master, and for me it seems that way, I suppose I don't understand well what this rebase should have done.
Can you explain me what's wrong and how to fix it please? Really sorry for the inconvenience.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing that potentially might have happened, is that your master is not up-to-date. Can you go to your master and pull the most recent version? You can use git log to see which commit your master is on. Today it should be d0433d6 (the id or the prefix of it you should see in your git log output on the top).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, the first time I tried to rebase directly on your master, not mine (which was not sync with yours).
I tried to redo the operation with my master, after setting it in sync with yours.
It looks good to me this time, I hope it is :-)

Expand Down
28 changes: 28 additions & 0 deletions lib/Elastica/Aggregation/ParentAggregation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace Elastica\Aggregation;

/**
* Class ParentAggregation.
*
* @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-parent-aggregation.html
*/
class ParentAggregation extends AbstractAggregation
{
protected function _getBaseName()
{
return 'parent';
}

/**
* Set the child type for this aggregation.
*
* @param string $field the child type that should be selected
*
* @return $this
*/
public function setType($type)
{
return $this->setParam('type', $type);
}
}
171 changes: 171 additions & 0 deletions test/Elastica/Aggregation/ParentAggregationTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
<?php

namespace Elastica\Test\Aggregation;

use Elastica\Aggregation\ParentAggregation;
use Elastica\Aggregation\Terms;
use Elastica\Document;
use Elastica\Query;
use Elastica\Type\Mapping;

class ParentAggregationTest extends BaseAggregationTest
{
protected function _getIndexForTest()
{
$client = $this->_getClient();
$index = $client->getIndex('testaggregationparent');
$index->create(['index' => ['number_of_shards' => 2, 'number_of_replicas' => 1]], true);

$type = $index->getType(\strtolower(
'typeparent'.\uniqid()
));

$mapping = new Mapping();
$mapping->setType($type);

$mapping = new Mapping($type, [
'text' => ['type' => 'keyword'],
'tags' => ['type' => 'keyword'],
'owner' => ['type' => 'keyword'],
'join' => [
'type' => 'join',
'relations' => [
'question' => 'answer',
],
],
]);

$type->setMapping($mapping);
$index->refresh();

$doc1 = new Document(1, [
'text' => 'this is the 1st question',
'tags' => [
'windows-server-2003',
'windows-server-2008',
'file-transfer',
],
'join' => [
'name' => 'question',
],
], $type->getName());

$doc2 = new Document(2, [
'text' => 'this is the 2nd question',
'tags' => [
'windows-server-2008',
'file-transfer',
],
'join' => [
'name' => 'question',
],
], $type->getName());

$index->addDocuments([$doc1, $doc2]);

$doc3 = new Document(3, [
'text' => 'this is an top answer, the 1st',
'owner' => 'Sam',
'join' => [
'name' => 'answer',
'parent' => 1,
],
], $type->getName(), $index->getName());

$doc4 = new Document(4, [
'text' => 'this is a top answer, the 2nd',
'owner' => 'Sam',
'join' => [
'name' => 'answer',
'parent' => 2,
],
], $type->getName(), $index->getName());

$doc5 = new Document(5, [
'text' => 'this is an answer, the 3rd',
'owner' => 'Troll',
'join' => [
'name' => 'answer',
'parent' => 2,
],
], $type->getName(), $index->getName());

$this->_getClient()->addDocuments([$doc3], ['routing' => 1]);
$this->_getClient()->addDocuments([$doc4, $doc5], ['routing' => 2]);
$index->refresh();

return $index;
}

/**
* @group functional
*/
public function testParentAggregation()
{
$agg = new ParentAggregation('question');
$agg->setType('answer');

$tags = new Terms('tags');
$tags->setField('tags');

$agg->addAggregation($tags);

$query = new Query();
$query->addAggregation($agg);

$index = $this->_getIndexForTest();
$aggregations = $index->search($query)->getAggregations();

// check parent aggregation exists
$this->assertArrayHasKey('question', $aggregations);

$parentAggregations = $aggregations['question'];

// check tags aggregation exists inside parent aggregation
$this->assertArrayHasKey('tags', $parentAggregations);
}

/**
* @group functional
*/
public function testParentAggregationCount()
{
$topNames = new Terms('top-names');
$topNames->setField('owner')
->setSize(10);

$toQuestions = new ParentAggregation('to-questions');
$toQuestions->setType('answer');

$topTags = new Terms('top-tags');
$topTags->setField('tags')
->setSize(10);

$toQuestions->addAggregation($topTags);
$topNames->addAggregation($toQuestions);

$query = new Query();
$query->addAggregation($topNames);

$index = $this->_getIndexForTest();
$aggregations = $index->search($query)->getAggregations();

$topNamesAggregation = $aggregations['top-names'];
$this->assertCount(2, $topNamesAggregation['buckets']);
$this->assertEquals(2, $topNamesAggregation['buckets'][0]['to-questions']['doc_count']);
$this->assertEquals(1, $topNamesAggregation['buckets'][1]['to-questions']['doc_count']);

$samTags = [
['key' => 'file-transfer', 'doc_count' => 2],
['key' => 'windows-server-2008', 'doc_count' => 2],
['key' => 'windows-server-2003', 'doc_count' => 1],
];
$this->assertEquals($samTags, $topNamesAggregation['buckets'][0]['to-questions']['top-tags']['buckets']);

$samTags = [
['key' => 'file-transfer', 'doc_count' => 1],
['key' => 'windows-server-2008', 'doc_count' => 1],
];
$this->assertEquals($samTags, $topNamesAggregation['buckets'][1]['to-questions']['top-tags']['buckets']);
}
}