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

EZP-27458: Provided Aggregation API #94

Merged
merged 1 commit into from Oct 6, 2020
Merged

EZP-27458: Provided Aggregation API #94

merged 1 commit into from Oct 6, 2020

Conversation

adamwojs
Copy link
Member

@adamwojs adamwojs commented Aug 5, 2020

Question Answer
JIRA issue EZP-27458
Type feature
Target eZ Platform version v3.2
BC breaks no
Tests pass ?
Doc needed yes

Introduction

Aggregation API is successor of Facet API, however aggregation is wider concept then facet.

Description

Aggregation MUST implement \eZ\Publish\API\Repository\Values\Content\Query\AggregationInterface interface

<?php

/**
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
 * @license For full copyright and license information view LICENSE file distributed with this source code.
 */
declare(strict_types=1);

namespace eZ\Publish\API\Repository\Values\Content\Query;

interface AggregationInterface
{
    public function getName(): string;
} 

Method getName() SHOULD return identifier specified by API user and unique across query e.g. price_stats, availability, content_type_facet.

One or more aggregations could be added using \eZ\Publish\API\Repository\Values\Content\Query::$aggregations property in exact same way as in case of sort clauses:

<?php 

use eZ\Publish\API\Repository\Values\Content\Query;
use eZ\Publish\API\Repository\Values\Content\Query\Aggregation\ContentTypeTermAggregation;
use eZ\Publish\API\Repository\Values\Content\Query\Aggregation\SectionTermAggregation;

$query = new Query();
$query->aggregations[] = new ContentTypeTermAggregation('content_type_facet');
$query->aggregations[] = new SectionTermAggregation('section_facet');

$results = $this->searchService->findContent($query);

// ... 

Aggregation Result MUST extends \eZ\Publish\API\Repository\Values\Content\Search\AggregationResult class

abstract class AggregationResult extends ValueObject
{
    /**
     * The name of the related aggregation.
     *
     * @var string
     */
    private $name;

    public function __construct(string $name)
    {
        parent::__construct();

        $this->name = $name;
    }

    public function getName(): string
    {
        return $this->name;
    }
}

Collection of aggregation results is accessible via \eZ\Publish\API\Repository\Values\Content\Search\SearchResult::$aggregations property.

// ...

foreach ($results->aggregations as $aggregation) {
    // Iterate over aggregations results
}

\eZ\Publish\API\Repository\Values\Content\Search\SearchResult::$aggregations property is \eZ\Publish\API\Repository\Values\Content\Search\AggregationResultCollection which offers the following API

Aggregations which are not supported by search engine MUST be ignored.

Aggregation results are limited to objects which match criteria specified in \eZ\Publish\API\Repository\Values\Content\Query::$filter and \eZ\Publish\API\Repository\Values\Content\Query::$query.

Supported aggregations

Aggregations could be classified by type of result:

  • Term aggregation: group by value and count object in each group
  • Range aggregation: count values in specified ranges
  • Stats aggregation: computes stats over numeric fields: minimum, average and maximum value, count and sum of values

or by aggregation subject:

  • Content aggregation
  • Location aggregation

with subset of Field Type specific aggregations.

Content aggregations

NameComment
ContentTypeTermAggregationTerm aggregation based on content type  
ContentTypeGroupTermAggregationTerm aggregation based on content type group 
DateMetadataRangeAggregationRange aggregation based on content creation/modification/publication date
LanguageTermAggregationTerm aggregation based on content language
ObjectStateTermAggregationTerm aggregation based on object state
SectionTermAggregationTerm aggregation based on section
UserMetadataTermAggregationTerm aggregation based on content owner/owner group or modifier
VisibilityTermAggregationTerm aggregation based on content/location visibility

Location aggregations

Location specific aggregations should implement \eZ\Publish\API\Repository\Values\Content\Query\Aggregation\LocationAggregationInterface marker interface.

Field type specific aggregations

Field type specific aggregations should implement \eZ\Publish\API\Repository\Values\Content\Query\Aggregation\FieldAggregationInterface interface

<?php

/**
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
 * @license For full copyright and license information view LICENSE file distributed with this source code.
 */
declare(strict_types=1);

namespace eZ\Publish\API\Repository\Values\Content\Query\Aggregation;

interface FieldAggregationInterface
{
    public function getContentTypeIdentifier(): string;

    public function getFieldDefinitionIdentifier(): string;
}

Class naming convention:

  • Field type identifier without vendor prefix (`ez` in our case)
  • Type of aggregation
  • Aggregation suffix

The following aggregations are field type specific

NameComment
CheckboxTermAggregation-
CountryTermAggregation-
DateRangeAggregation-
DateTimeRangeAggregation-
FloatRangeAggregation-
FloatStatsAggregation-
IntegerRangeAggregation-
IntegerStatsAggregation-
KeywordTermAggregation-
SelectionTermAggregation-
TimeRangeAggregation-

Usage example:

<?php

$query = new Query();
$query->aggregations[] = new CheckboxTermAggregation('availability', 'product', 'is_available');
$query->aggregations[] = new KeywordTermAggregation('tags', 'product', 'tags');
$query->aggregations[] = new SelectionTermAggregation('categories', 'product', 'category');

Raw aggregations

Raw aggregations allows to compute aggregation for specified search index field name.

  • \eZ\Publish\API\Repository\Values\Content\Query\Aggregation\RawRangeAggregation
  • \eZ\Publish\API\Repository\Values\Content\Query\Aggregation\RawStatsAggregation
  • \eZ\Publish\API\Repository\Values\Content\Query\Aggregation\RawTermAggregation
$query = new LocationQuery();
$query->filter = new MatchAll();
$query->aggregations[] = new RawRangeAggregation('priority', 'priority_id', [
    new Range(1, 10),  // low priority locations
    new Range(10, 100) // high priority
]);
$query->aggregations[] = new RawStatsAggregation('location_depth_stats', 'depth_i');
$query->aggregations[] = new RawTermAggregation('content_per_content_type', 'content_type_id_id');

TODO

  • Initial implementaion
  • Deprecate Facet API
  • Introduce \eZ\Publish\Core\Search\Common\FieldNameResolver::getAggregationFieldName
  • Consider to intoroduce AggregationCollection and AggregationResultCollection (similar to \eZ\Publish\API\Repository\Values\ContentType\FieldDefinitionCollection)
  • Impl. \eZ\Publish\Core\FieldType\Float\Type::isSearchable (EZP-31817: Enabled ezfloat values indexing #103)
  • Impl. ElasticSearch (ezsystems/ezplatform-elastic-search-engine#13)
  • Impl. Solr support (EZP-27458: Aggregation API ezplatform-solr-search-engine#192)
  • Rename UserTermAggregation to UserMetadataTermAggregation
  • Rename DateRangeAggregation to DateMetadataRangeAggregation
  • Remove $limit and $minCount from `\eZ\Publish\API\Repository\Values\Content\Query\Aggregation\AbstractTermAggregation::__construct`
  • Fix https://jira.ez.no/browse/EZP-31741

Checklist:

  • PR description is updated.
  • Tests are implemented.
  • Added code follows Coding Standards (use $ composer fix-cs).
  • PR is ready for a review.

@adamwojs adamwojs added the Feature New feature or request label Aug 5, 2020
@adamwojs adamwojs self-assigned this Aug 5, 2020
@ezsystems ezsystems deleted a comment from sonarcloud bot Sep 15, 2020
@ezsystems ezsystems deleted a comment from sonarcloud bot Sep 15, 2020
@ezsystems ezsystems deleted a comment from sonarcloud bot Sep 15, 2020
@ezsystems ezsystems deleted a comment from sonarcloud bot Sep 15, 2020
@ezsystems ezsystems deleted a comment from sonarcloud bot Sep 16, 2020
@ezsystems ezsystems deleted a comment from sonarcloud bot Sep 17, 2020
@adamwojs adamwojs marked this pull request as ready for review September 21, 2020 06:46
@ezsystems ezsystems deleted a comment from sonarcloud bot Sep 22, 2020
@adamwojs adamwojs force-pushed the aggregations branch 2 times, most recently from f7ea204 to 23d440c Compare September 24, 2020 20:31
@ezsystems ezsystems deleted a comment from sonarcloud bot Oct 4, 2020
@ezsystems ezsystems deleted a comment from sonarcloud bot Oct 5, 2020
* @group search
* @group aggregations
*/
final class SearchServiceAggregationTest extends BaseTest
Copy link
Contributor

Choose a reason for hiding this comment

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

the class is quite long, can be split into smaller ones? ex. by TermAggregation, test case etc.
Smaller classes will be more friendly to maintain in future

Copy link
Member Author

Choose a reason for hiding this comment

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

I agree. I will split this class into smaller once (by Aggregation) in follow up PR.

@ezsystems ezsystems deleted a comment from sonarcloud bot Oct 6, 2020
@ezsystems ezsystems deleted a comment from sonarcloud bot Oct 6, 2020
@alongosz alongosz changed the title EZP-27458: Aggregation API EZP-27458: Provided Aggregation API Oct 6, 2020
@ezsystems ezsystems deleted a comment from sonarcloud bot Oct 6, 2020
@adamwojs
Copy link
Member Author

adamwojs commented Oct 6, 2020

Merging. Any further comments and suggestions will be taken into account as follow up PRs.

@adamwojs adamwojs merged commit d1b8505 into master Oct 6, 2020
@adamwojs adamwojs deleted the aggregations branch October 6, 2020 14:14
@sonarcloud
Copy link

sonarcloud bot commented Oct 6, 2020

Kudos, SonarCloud Quality Gate passed!

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities (and Security Hotspot 0 Security Hotspots to review)
Code Smell A 11 Code Smells

No Coverage information No Coverage information
2.0% 2.0% Duplication

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature New feature or request
6 participants