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) -> Thi does not work.
This is an example :
{code:java} @Field( name = CATEGORIES, bridge = @FieldBridge(impl = StringCollectionFieldBridge.class), analyze = Analyze.NO ) @Facet(forField = CATEGORIES) @ElementCollection private List<String> categories = new ArrayList<String>(); {code}
I register my facets like this :
{code:java} 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); } {code}
and get facets values like this :
{code:java} 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(); } } ) ); } {code}
So when I perform this code and try to get facets values, I get a list of String like :
{code:java} ["[category1, category2]", "[category1]" , "[category2 ] "] {code}
This is totally normal regarding the code in the Class
{code:java} org.hibernate.search.engine.spi.DocumentBuilderIndexedEntity {code}
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 :
{code:java} // 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; {code}
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 :
{code:java} // In a switch case STRING: { String stringValue = value.toString(); if ( stringValue.isEmpty() ) { return null; } facetField = new SortedSetDocValuesFacetField( facetMetadata.getFacetName(), stringValue ); break; } {code}
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.
Thanks for the help. |
|