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 Post Meta and Generic Term Aggregations #56

Merged
merged 8 commits into from
Oct 17, 2023

Conversation

kevinfodness
Copy link
Member

@kevinfodness kevinfodness commented Oct 6, 2023

  • Adds a new Post Meta aggregation to aggregate based on meta value.
  • Abstracts the Post Meta, Post Type, and Taxonomy aggregations to use a new generic Term aggregation, which could also be used standalone provided that a user specifies the query var and term field.

Summary by CodeRabbit

  • New Feature: Introduced new data aggregation options, enhancing the software's ability to organize and analyze data. Users can now aggregate data based on post meta and generic term fields, providing more flexibility and customization.
  • Refactor: Improved the structure of several classes, making the software more modular and configurable. This change enhances the software's adaptability to different use cases.
  • Style: Updated the PHP_CodeSniffer standard for Elasticsearch Extensions to prevent undesirable behavior with phpstan annotations, ensuring code consistency and readability.
  • Documentation: Added detailed inline comments to new parameters and methods, making the software easier to understand and use.

Copy link
Contributor

@mboynes mboynes left a comment

Choose a reason for hiding this comment

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

Awesome cleanup!

lib/aggregations/class-post-meta.php Outdated Show resolved Hide resolved
* Configure the Post_Meta aggregation.
*
* @param DSL $dsl The DSL object, initialized with the map from the adapter.
* @param array $args Optional. Additional arguments to pass to the aggregation.
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's important to expand the phpdoc here to document all the arguments the aggregation accepts (comment applies throughout)

Copy link
Member Author

Choose a reason for hiding this comment

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

Good call, will do

@coderabbitai
Copy link

coderabbitai bot commented Oct 17, 2023

Walkthrough

The changes introduce new classes and methods for data aggregation based on post meta and generic term fields in Elasticsearch. The codebase's functionality is expanded, providing more options for data aggregation. The changes also enhance the modularity and configurability of the classes by adding new optional parameters to several methods. The PHP_CodeSniffer standard for Elasticsearch Extensions is also modified.

Changes

File Summary
lib/adapters/class-adapter.php Introduced new aggregation classes (Post_Meta, Term, Term_Field) and methods (add_post_meta_aggregation(), add_term_aggregation()) for data aggregation based on post meta and generic term fields.
lib/aggregations/class-post-meta.php Introduced a new class Post_Meta for building the DSL and requests for aggregations, and holding the result of the aggregation.
lib/aggregations/class-post-type.php Changed the inheritance of the Post_Type class from Aggregation to Term and removed unnecessary methods.
lib/aggregations/class-taxonomy.php Changed the inheritance of the Taxonomy class from Aggregation to Term and removed unnecessary methods.
lib/aggregations/class-term.php Introduced a new class Term for building the DSL and requests for term aggregations in Elasticsearch.
lib/class-controller.php Added new optional parameters to several methods for more flexibility and customization options for configuring aggregations.
lib/adapters/class-generic.php Modified the return type declaration of the get_field_map() method.
lib/class-factory.php Swapped the implementations of two adapter functions.
.phpcs.xml Modified the PHP_CodeSniffer standard for Elasticsearch Extensions.

Tips

Chat with CodeRabbit Bot (@coderabbitai)

  • Mention @coderabbitai in any review comment for bot assistance.
  • Note: Review comments are made on code diffs or files, not on the PR overview.

Pause Incremental Reviews

  • Insert @coderabbitai: ignore in the PR description to halt the bot's ongoing reviews. Remove the line to resume.
  • Additionally, enter @coderabbitai pause to halt the bot's ongoing reviews as any issue or review comment. To
    resume reviews, enter @coderabbitai resume as any issue or review comment.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review Status

Actionable comments generated: 2

Commits Files that changed from the base of the PR and between 1f23213 and 1edff69.
Files selected for processing (6)
  • lib/adapters/class-adapter.php (3 hunks)
  • lib/aggregations/class-post-meta.php (1 hunks)
  • lib/aggregations/class-post-type.php (3 hunks)
  • lib/aggregations/class-taxonomy.php (4 hunks)
  • lib/aggregations/class-term.php (1 hunks)
  • lib/class-controller.php (9 hunks)
Files skipped from review due to trivial changes (1)
  • lib/aggregations/class-taxonomy.php
Additional comments (Suppressed): 18
lib/adapters/class-adapter.php (3)
  • 11-21: The new hunk introduces two new classes Post_Meta and Term from the Elasticsearch_Extensions\Aggregations namespace. Ensure these classes are implemented correctly and are available in the specified namespace.

  • 134-145: The add_post_meta_aggregation method is introduced to add a new post meta aggregation to the list of active aggregations. It uses the Post_Meta class which is new. Ensure that the Post_Meta class is implemented correctly and that it accepts the arguments as passed in this method.

  • 172-197: The add_term_aggregation method is introduced to add a new generic term aggregation to the list of active aggregations. It uses the Term class which is new. Ensure that the Term class is implemented correctly and that it accepts the arguments as passed in this method.

lib/aggregations/class-post-type.php (3)
  • 17-17: The Post_Type class now extends Term instead of Aggregation. Ensure that the Term class provides all the necessary methods and properties that Post_Type requires, and that it doesn't introduce any unwanted behavior.

  • 25-30: The __construct() method now sets a new property term_field before calling the parent constructor. This property seems to be used for mapping the field for term aggregations. Ensure that this property is properly used in the parent class and that the field mapping is correct.

  • 56-58: The request() method has been removed. This method was previously responsible for getting the DSL for the aggregation to add to the Elasticsearch request object. If this functionality is now handled elsewhere, ensure that it is correctly implemented and that the removal of this method doesn't break any existing functionality.

lib/aggregations/class-term.php (3)
  • 1-89: The new Term class extends the Aggregation class and provides methods for building the DSL and requests for term aggregations in Elasticsearch. It introduces two new properties: $relation and $term_field. The filter() method generates an array of DSL fragments based on the query values and the logical relationship between them. The parse_buckets() method parses raw Elasticsearch aggregation buckets into Bucket objects. The request() method returns a DSL fragment for the aggregation to add to the Elasticsearch request object. The code seems to be logically sound and well-structured.

  • 66-77: The parse_buckets() method creates a new Bucket object for each bucket in $buckets. It's important to ensure that each $bucket contains the keys 'key' and 'doc_count', as these are used to create the Bucket objects. If these keys are not present in any of the $buckets, it could lead to undefined index errors. Consider adding error handling or checks to ensure these keys exist.

  • 86-88: The request() method returns a DSL fragment for the aggregation to add to the Elasticsearch request object. Ensure that the aggregate_terms() method of the $this->dsl object accepts the $this->query_var and $this->term_field as parameters and returns the expected output.

lib/class-controller.php (9)
  • 57-77: The function signature for enable_co_authors_plus_aggregation() has been updated to include a more detailed array of arguments. Ensure that all calls to this function throughout the codebase have been updated to match the new signature.

  • 84-96: The function signature for enable_custom_date_range_aggregation() has been updated to include a more detailed array of arguments. Ensure that all calls to this function throughout the codebase have been updated to match the new signature.

  • 114-132: The function signature for enable_post_date_aggregation() has been updated to include a more detailed array of arguments. Ensure that all calls to this function throughout the codebase have been updated to match the new signature.

  • 139-163: A new function enable_post_meta_aggregation() has been added. This function allows for the creation of aggregations based on post meta. Ensure that this new function is being used correctly throughout the codebase.

  • 170-190: The function signature for enable_post_type_aggregation() has been updated to include a more detailed array of arguments. Ensure that all calls to this function throughout the codebase have been updated to match the new signature.

  • 197-215: The function signature for enable_relative_date_aggregation() has been updated to include a more detailed array of arguments. Ensure that all calls to this function throughout the codebase have been updated to match the new signature.

  • 254-275: > Note: This review was outside of the patch, so it was mapped to the patch with the greatest overlap. Original lines [222-275]

The function signature for enable_taxonomy_aggregation() has been updated to include a more detailed array of arguments. Ensure that all calls to this function throughout the codebase have been updated to match the new signature.

  • 282-308: A new function enable_term_aggregation() has been added. This function allows for the creation of generic Elasticsearch 'term' aggregations. Ensure that this new function is being used correctly throughout the codebase.

  • 332-338: The return type of get_aggregations() has been updated from array to Aggregation[]. Ensure that all calls to this function throughout the codebase have been updated to handle the new return type.

Comment on lines +1 to +43
<?php
/**
* Elasticsearch Extensions: Post_Meta Aggregation Class
*
* @package Elasticsearch_Extensions
*/

namespace Elasticsearch_Extensions\Aggregations;

use Elasticsearch_Extensions\DSL;

/**
* Post_Meta aggregation class. Responsible for building the DSL and requests
* for aggregations as well as holding the result of the aggregation after a
* response was received.
*/
class Post_Meta extends Term {

/**
* The postmeta key this aggregation is associated with.
*
* @var string
*/
protected string $meta_key;

/**
* Configure the Post_Meta aggregation.
*
* @param DSL $dsl The DSL object, initialized with the map from the adapter.
* @param array $args Optional. Additional arguments to pass to the aggregation.
*/
public function __construct( DSL $dsl, array $args ) {
if ( ! empty( $args['meta_key'] ) ) {
$this->label = ucwords( str_replace( [ '-', '_' ], ' ', $args['meta_key'] ) );
$this->meta_key = $args['meta_key'];
$this->query_var = 'post_meta_' . $args['meta_key'];
$this->term_field = $dsl->map_meta_field( $args['meta_key'], $args['data_type'] ?? '' );
unset( $args['meta_key'] );
}

parent::__construct( $dsl, $args );
}
}
Copy link

Choose a reason for hiding this comment

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

The Post_Meta class extends the Term class and adds a meta_key property. It overrides the constructor to accept a meta_key argument and uses it to set the label, meta_key, query_var, and term_field properties. The meta_key argument is then removed from the $args array before calling the parent constructor. This class seems to be well-structured and follows the principles of object-oriented programming. However, there is no error handling or validation for the meta_key argument. If it's not provided or is an empty string, the class properties will not be properly initialized, which could lead to unexpected behavior or errors later on. Consider adding a check for this and throwing an exception if it's not valid.

	public function __construct( DSL $dsl, array $args ) {
+		if ( empty( $args['meta_key'] ) ) {
+			throw new \InvalidArgumentException( 'The meta_key argument is required and cannot be empty.' );
+		}
		if ( ! empty( $args['meta_key'] ) ) {
			$this->label      = ucwords( str_replace( [ '-', '_' ], ' ', $args['meta_key'] ) );
			$this->meta_key   = $args['meta_key'];
			$this->query_var  = 'post_meta_' . $args['meta_key'];
			$this->term_field = $dsl->map_meta_field( $args['meta_key'], $args['data_type'] ?? '' );
			unset( $args['meta_key'] );
		}

		parent::__construct( $dsl, $args );
	}
}

Comment on lines +42 to +58
public function filter(): array {
if ( empty( $this->query_values ) ) {
return [];
}

// Fork for AND vs. OR logic.
$filters = [];
if ( 'OR' === $this->relation ) {
$filters[] = $this->dsl->terms( $this->term_field, $this->query_values );
} else {
foreach ( $this->query_values as $query_value ) {
$filters[] = $this->dsl->terms( $this->term_field, $query_value );
}
}

return $filters;
}
Copy link

Choose a reason for hiding this comment

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

The filter() method uses an if condition to check if $this->query_values is empty and returns an empty array if true. This is a good practice as it prevents unnecessary processing when there are no query values. However, the method could be optimized by returning the array immediately after it's populated, instead of storing it in a variable and returning it at the end. This would make the code more efficient and easier to read.

	public function filter(): array {
		if ( empty( $this->query_values ) ) {
			return [];
		}

		// Fork for AND vs. OR logic.
		if ( 'OR' === $this->relation ) {
			return [$this->dsl->terms( $this->term_field, $this->query_values )];
		} else {
			$filters = [];
			foreach ( $this->query_values as $query_value ) {
				$filters[] = $this->dsl->terms( $this->term_field, $query_value );
			}
			return $filters;
		}
	}

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review Status

Actionable comments generated: 0

Commits Files that changed from the base of the PR and between 1edff69 and b7176b4.
Files selected for processing (4)
  • lib/adapters/class-adapter.php (10 hunks)
  • lib/adapters/class-generic.php (1 hunks)
  • lib/class-controller.php (9 hunks)
  • lib/class-factory.php (1 hunks)
Additional comments (Suppressed): 20
lib/adapters/class-generic.php (1)
  • 16-22: The return type of get_field_map() method has been updated to array<string, string>. Ensure that all calls to this method throughout the codebase are expecting this new return type. Also, verify that the returned array always adheres to this type.
lib/class-factory.php (1)
  • 67-86: The order of the searchpress_adapter() and vip_enterprise_search_adapter() methods has been swapped. Ensure that this does not affect any dependencies or the order of execution in the codebase.
lib/adapters/class-adapter.php (9)
  • 11-21: The new hunk introduces two new classes Post_Meta and Term for use in the Adapter class. Ensure these classes are correctly implemented and tested.

  • 110-130: The method add_cap_author_aggregation now has a more detailed docstring and a more specific type hint for the $args parameter. This is a good improvement for code readability and maintainability.

  • 133-146: The method add_custom_date_range_aggregation now has a more detailed docstring and a more specific type hint for the $args parameter. This is a good improvement for code readability and maintainability.

  • 149-217: The methods add_post_date_aggregation, add_post_meta_aggregation, and add_post_type_aggregation now have more detailed docstrings and more specific type hints for their parameters. This is a good improvement for code readability and maintainability.

  • 241-301: > Note: This review was outside of the patch, so it was mapped to the patch with the greatest overlap. Original lines [220-296]

The methods add_relative_date_aggregation, add_taxonomy_aggregation, and add_term_aggregation now have more detailed docstrings and more specific type hints for their parameters. This is a good improvement for code readability and maintainability.

  • 364-370: The return type hint for the get_field_map method has been updated to array<string, string>. This is a good improvement for code readability and maintainability.

  • 410-418: The type hint for the $post_types parameter in the get_searchable_post_types method has been updated to string[]. This is a good improvement for code readability and maintainability.

  • 440-446: The type hint for the $aggregations parameter in the parse_aggregations method has been updated to array<string, mixed>. This is a good improvement for code readability and maintainability.

  • 454-460: The type hint for the $args parameter in the suggest_posts method has been updated to array{subtypes?: string[], page?: int, per_page?: int, include?: int[], exclude?: int[]}. This is a good improvement for code readability and maintainability.

lib/class-controller.php (9)
  • 57-77: The function signature for enable_co_authors_plus_aggregation() has been updated to include a more detailed array of arguments. Ensure that all calls to this function throughout the codebase have been updated to match the new signature.

  • 84-97: The function signature for enable_custom_date_range_aggregation() has been updated to include a more detailed array of arguments. Ensure that all calls to this function throughout the codebase have been updated to match the new signature.

  • 115-133: The function signature for enable_post_date_aggregation() has been updated to include a more detailed array of arguments. Ensure that all calls to this function throughout the codebase have been updated to match the new signature.

  • 140-169: A new function enable_post_meta_aggregation() has been added. This function allows for the creation of aggregations based on post meta. Ensure that this new function is being used correctly throughout the codebase.

  • 171-191: The function signature for enable_post_type_aggregation() has been updated to include a more detailed array of arguments. Ensure that all calls to this function throughout the codebase have been updated to match the new signature.

  • 198-216: The function signature for enable_relative_date_aggregation() has been updated to include a more detailed array of arguments. Ensure that all calls to this function throughout the codebase have been updated to match the new signature.

  • 255-276: > Note: This review was outside of the patch, so it was mapped to the patch with the greatest overlap. Original lines [223-276]

The function signature for enable_taxonomy_aggregation() has been updated to include a more detailed array of arguments. Ensure that all calls to this function throughout the codebase have been updated to match the new signature.

  • 283-309: A new function enable_term_aggregation() has been added. This function allows for the creation of generic Elasticsearch 'term' aggregations. Ensure that this new function is being used correctly throughout the codebase.

  • 333-339: The return type of get_aggregations() has been updated to Aggregation[] from array. Ensure that all calls to this function throughout the codebase have been updated to handle the new return type.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review Status

Actionable comments generated: 0

Commits Files that changed from the base of the PR and between b7176b4 and ccaad04.
Files selected for processing (3)
  • .phpcs.xml (1 hunks)
  • lib/adapters/class-adapter.php (10 hunks)
  • lib/class-controller.php (9 hunks)
Files skipped from review due to trivial changes (1)
  • .phpcs.xml
Additional comments (Suppressed): 19
lib/class-controller.php (9)
  • 57-77: The function signature has been updated to include a more detailed array of arguments. Ensure that all calls to this function throughout the codebase have been updated to match the new signature.

  • 84-97: The function signature has been updated to include a more detailed array of arguments. Ensure that all calls to this function throughout the codebase have been updated to match the new signature.

  • 115-133: The function signature has been updated to include a more detailed array of arguments. Ensure that all calls to this function throughout the codebase have been updated to match the new signature.

  • 140-164: A new method enable_post_meta_aggregation has been added. This method allows for aggregations based on post meta. Ensure that this new method is properly integrated and called in the codebase.

  • 171-191: The function signature has been updated to include a more detailed array of arguments. Ensure that all calls to this function throughout the codebase have been updated to match the new signature.

  • 198-216: The function signature has been updated to include a more detailed array of arguments. Ensure that all calls to this function throughout the codebase have been updated to match the new signature.

  • 255-276: > Note: This review was outside of the patch, so it was mapped to the patch with the greatest overlap. Original lines [223-276]

The function signature has been updated to include a more detailed array of arguments. Ensure that all calls to this function throughout the codebase have been updated to match the new signature.

  • 284-309: A new method enable_term_aggregation has been added. This method allows for a generic Elasticsearch 'term' aggregation. Ensure that this new method is properly integrated and called in the codebase.

  • 333-339: The return type of the get_aggregations method has been refined to Aggregation[]. Ensure that all calls to this function throughout the codebase have been updated to handle the new return type.

lib/adapters/class-adapter.php (10)
  • 11-21: The new hunk introduces two new classes Post_Meta and Term for use in the Adapter class. Ensure these classes are properly defined and imported.

  • 110-130: The function signature for add_cap_author_aggregation has been updated with a more detailed array structure for $args. Ensure that all calls to this function throughout the codebase have been updated to match the new signature.

  • 133-146: The function signature for add_custom_date_range_aggregation has been updated with a more detailed array structure for $args. Ensure that all calls to this function throughout the codebase have been updated to match the new signature.

  • 149-217: The function signatures for add_post_date_aggregation, add_post_meta_aggregation, and add_post_type_aggregation have been updated with more detailed array structures for $args. Ensure that all calls to these functions throughout the codebase have been updated to match the new signatures.

  • 220-238: The function signature for add_relative_date_aggregation has been updated with a more detailed array structure for $args. Ensure that all calls to this function throughout the codebase have been updated to match the new signature.

  • 241-296: The function signatures for add_taxonomy_aggregation and add_term_aggregation have been updated with more detailed array structures for $args. Ensure that all calls to these functions throughout the codebase have been updated to match the new signatures.

  • 364-370: The return type of the get_field_map() method has been refined to array<string, string>. Ensure that all subclasses of Adapter return an array of string keys and values in their implementation of this method.

  • 410-418: The function signature for get_searchable_post_types has been updated to specify that $post_types is an array of strings. Ensure that all calls to this function throughout the codebase pass an array of strings.

  • 440-446: The function signature for parse_aggregations has been updated to specify that $aggregations is an array with string keys and mixed values. Ensure that all calls to this function throughout the codebase pass an array of this structure.

  • 454-460: The function signature for suggest_posts has been updated with a more detailed array structure for $args. Ensure that all calls to this function throughout the codebase have been updated to match the new signature.

@kevinfodness kevinfodness merged commit 5085e09 into main Oct 17, 2023
6 checks passed
@kevinfodness kevinfodness deleted the feature/postmeta-aggregation branch October 17, 2023 01:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants