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

HSEARCH-4577 @ProjectionConstructor: aggregating multi-valued field/object projections in Set, SortedSet, etc. instead of List #4329

Conversation

marko-bekhta
Copy link
Member

@marko-bekhta marko-bekhta commented Sep 26, 2024

https://hibernate.atlassian.net/browse/HSEARCH-4577

for now, just to get a CI run 🙈
still need more tests, docs and migration guide udpates


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license
and can be relicensed under the terms of the LGPL v2.1 license in the future at the maintainers' discretion.
For more information on licensing, please check here.


@marko-bekhta marko-bekhta force-pushed the feat/HSEARCH-4577-ProjectionConstructor-aggregating-multi-valued-fieldobject-projections-in-Set-SortedSet branch from de93c99 to c212a42 Compare September 27, 2024 06:45
@marko-bekhta marko-bekhta force-pushed the feat/HSEARCH-4577-ProjectionConstructor-aggregating-multi-valued-fieldobject-projections-in-Set-SortedSet branch from c212a42 to 143fd90 Compare September 27, 2024 14:53
* @return A new step to define optional parameters for the multi-valued projections.
* @see MultiProjectionTypeReference
*/
<C> FieldProjectionOptionsStep<?, C> multi(MultiProjectionTypeReference<C, T> collectionTypeReference);
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 wonder whether renaming this from multi to container and then adding built-in type references for optional is a good idea ...

Copy link
Member

Choose a reason for hiding this comment

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

+1 for container as the default is already "multi", so it feels a bit weird to introduce a "multi".

However, don't we expose "multi" methods in other DSLs, especially in the search DSL? We'd need to be consistent...

Copy link
Member Author

@marko-bekhta marko-bekhta Sep 27, 2024

Choose a reason for hiding this comment

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

yeah we also have that HighlightProjectionOptionsStep#single() ...
It would be nice if we can just deprecate all that and do something like

.select(
	f -> f.composite()
		.from(
			f.highlight( "anotherString" ),  // default list as it is now
			f.highlight( "anotherString" ).accumulator(ProjectionAccumulator.single() ), // instead of calling  f.highlight( "anotherString" ).single(),
			f.highlight( "anotherString" ).accumulator(ProjectionAccumulator.optional() ), // still single but wraps the string into an optional
			f.highlight( "anotherString" ).accumulator(ProjectionAccumulator.sortedSet() ), // multi but non-default collection type
			f.highlight( "anotherString" ).accumulator(ProjectionAccumulator.sortedSet(customComparator) ), // multi but non-default collection type with custom comparator
			f.highlight( "anotherString" ).accumulator(ProjectionAccumulator.array() ), // multi but non-default collection type
			f.highlight( "anotherString" ).accumulator(CustomUserDefinedThing.smth() ), // whatever the user came up with
		).asList()
)

(well and the same thing in other places: deprecate the multi and give this accumulator as an alternative)

* @param <V> The type of the elements in the collection.
*/
@Incubating
public interface MultiProjectionTypeReference<C, V> {
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 couldn't come up with a better name for this one .... so any suggestions are more than welcome 😃

Copy link
Member

Choose a reason for hiding this comment

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

Couldn't you just promote ProjectionAccumulator to API, and use ProjectionAccumulator.Provider? It's admittedly a complex interface, but it's what we use under the hood, and if you provide implementations for the main container types, users will only need to implement it very rarely.

Then you could rename ProjectionAccumulator#single() to nullable() and introduce optional().

Well, you'll probably need to create a new interface, and juggle with inheritance and deprecations, but you see what I mean.

Copy link
Member Author

Choose a reason for hiding this comment

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

It's admittedly a complex interface

yeah ... that's why I was thinking that since we are using this index-based approach for transformation operations in the accumulator that most implementations would still be backed by a list as a temporary storage option and the only difference would be the R finish(A accumulated) that performs the final transformation. Hence, I thought extracting this method (as convert()) would work for the users with some custom collections and we'd just delegate to in the list-based accumulator.

but let me see how promoting the accumulator to the API would work out 😃

Copy link
Member

Choose a reason for hiding this comment

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

Fair enough, either solution has its merits. I'll let you have a look and decide :)

Hence, I thought extracting this method (as convert()) would work for the users with some custom collections and we'd just delegate to in the list-based accumulator.

Note you could also provide a static <V, C> Provider<V, C> simple(Function<List<V>, C> converter) "factory method" to allow simple list-based implementations.

Copy link
Member

@yrodiere yrodiere Sep 27, 2024

Choose a reason for hiding this comment

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

Note you could also provide a static <V, C> Provider<V, C> simple(Function<List<V>, C> converter) "factory method" to allow simple list-based implementations.

#4334 😀

EDIT: It could probably be generalized to any type of "delegate" accumulator, in particular to allow single-valued simple accumulators, but... this is probably enough?

@marko-bekhta marko-bekhta force-pushed the feat/HSEARCH-4577-ProjectionConstructor-aggregating-multi-valued-fieldobject-projections-in-Set-SortedSet branch from 143fd90 to 7e7e889 Compare September 27, 2024 15:14
Copy link

sonarcloud bot commented Oct 1, 2024

@marko-bekhta
Copy link
Member Author

superseded by #4344

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.

2 participants