Issue
I'am coding a simple query which targeting multiple index :
//targetIndexes is a list of indexes
searchSession.search(targetIndexes).extension(ElasticsearchExtension.get())
Now I simply want a "countByDocumentType". It means that I want the number of result grouped by the index type. For this I have got two fields already present in my stored index, but I can't query them with hibernate search, damn it ! Actually, elastic search adds its native field named "_index" to allow filtering by index. Hibernate search add also its native field named "_entity_type". But I neither can query on "_index" nor "_entity_type" with hibernate search using aggregation like this :
AggregationKey<Map<String, Long>> countsByEntityKey = AggregationKey.of( "countsByEntity" );
...where(...).aggregation(countsByEntityKey, f -> f.terms()
.field( "_entity_type", String.class ));
So do I really need to pollute all my classes by adding a custom third field into each hibernate mapped entities in order to be able to query on a specific index ?
@Indexed
public class MyIndexedEntity {
...
@GenericField
public String getEntityName() {
return this.getClass.getName();
}
}
Thanks for your answer
Solution
You can't refer to fields that are not part of the Hibernate Search mapping in the Hibernate Search DSL yet.
I'd suggest using a native aggregation:
AggregationKey<JsonObject> countsByEntityTypeKey = AggregationKey.of( "countsByEntityType" );
SearchResult<Book> result = searchSession.search( Arrays.asList( Book.class, Author.class ) )
.extension( ElasticsearchExtension.get() )
.where( f -> f.matchAll() )
.aggregation( countsByEntityTypeKey, f -> f.fromJson( "{\"terms\":{\"field\": \"_entity_type\"}}" ) )
.fetch( 20 );
JsonObject countsByEntityTypeAsJson = result.aggregation( countsByEntityTypeKey );
Map<String, Long> countsByEntityType = new HashMap<>();
for ( JsonElement bucket: countsByEntityTypeAsJson.get("buckets").getAsJsonArray() ) {
JsonObject bucketObject = bucket.getAsJsonObject();
countsByEntityType.put( bucketObject.get( "key" ).getAsString(),
bucketObject.get( "doc_count" ).getAsLong() );
}
You can still use the (less verbose) Hibernate Search APIs for everything else, in the same query.
Answered By - yrodiere