@Facet on container (Iterable, Array, ...) properties indexes the container's toString()

Description

Hi everybody,

I am trying to work with hibernate search facets.
I have three use cases :

  • Faceting on a simple field -> This is OK.

  • Faceting on a Collection of entity (with an IndexEmbeded) -> This is OK.

  • Faceting on a simple Collection (like a Collection of String) -> This does not work.

This is an example :

1 2 3 4 5 6 7 8 @Field( name = CATEGORIES, bridge = @FieldBridge(impl = StringCollectionFieldBridge.class), analyze = Analyze.NO ) @Facet(forField = CATEGORIES) @ElementCollection private List<String> categories = new ArrayList<String>();

I register my facets like this :

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 private FacetManager getFacetManager() { return getFullTextQuery().getFacetManager(); } protected void registerFacet(FacetingRequest facetingRequest) { getFacetManager().enableFaceting(facetingRequest); } protected void registerFacet(String facetName, String fieldPath) { FacetingRequest facetingRequest = getFactory().getDefaultQueryBuilder().facet() .name(facetName) .onField(fieldPath) .discrete() .includeZeroCounts(false) .createFacetingRequest(); registerFacet(facetingRequest); }

and get facets values like this :

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 protected Collection<Facet> getFacets(String facetName) { return getFacetManager().getFacets(facetName); } @Override public final List<String> listFacetValues(String facetName) { return Lists.newArrayList( Iterables.transform( getFacets(facetName), new SerializableFunction<Facet, String>() { @Override public String apply(Facet facet) { return facet.getValue(); } } ) ); }

So when I perform this code and try to get facets values, I get a list of String like :

1 ["[category1, category2]", "[category1]", "[category2]"]

This is totally normal regarding the code in the Class

1 org.hibernate.search.engine.spi.DocumentBuilderIndexedEntity

In fact, facets work well on a Collection of entities because it is detected that there is embeded objects. So the method buildDocumentFieldsForEmbeddedObjects is called.
In this method, ther is something like this :

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 // In a switch case COLLECTION: Collection<?> collection = objectInitializer.initializeCollection( (Collection<?>) value ); for ( Object collectionValue : collection ) { buildDocumentFields( collectionValue, doc, faceting, embeddedTypeMetadata, fieldToAnalyzerMap, processedFieldNames, conversionContext, objectInitializer, embeddedBoost, true ); } break;

So it's works because you iterate on each item. Moreover, multivalued (a FacetHandling property) is set to true.

However, on my use case, it is not an embeded. So multivalued property is set to false and the method which is called is this buildDocumentFieldsForProperties which called getFacetDocValues method on a collection object. In this method ther is something like this :

1 2 3 4 5 6 7 8 9 10 11 12 // In a switch case STRING: { String stringValue = value.toString(); if ( stringValue.isEmpty() ) { return null; } facetField = new SortedSetDocValuesFacetField( facetMetadata.getFacetName(), stringValue ); break; }

This is applied directly on a collection object. That's why I get the result above.

I think I have a solution to fix the issue but I would like to know if this is really an issue or if I misunderstood something.
I have put the file DocumentBuilderIndexedEntity.java with my fix.

Thanks for the help.

Environment

None

Status

Assignee

Yoann Rodière

Reporter

Julien Benichou

Labels

Suitable for new contributors

None

Feedback Requested

None

Components

Fix versions

Affects versions

5.5.5.Final

Priority

Major