If you don’t want to put the fields on the permissionBinder object field, but on its parent instead… just remove the object field, and put the fields on the parent?
public class MapValueBinder implements PropertyBinder {
private static final Logger log = LoggerFactory.getLogger(MapValueBinder.class);
@Override
public void bind(PropertyBindingContext context) {
context.dependencies().useRootOnly();
IndexSchemaElement schemaElement = context.indexSchemaElement();
- IndexSchemaObjectField userMetadataField = schemaElement.objectField("permissionBinder");
- userMetadataField.fieldTemplate("permissionTemplate", IndexFieldTypeFactory::asString);
+ schemaElement.fieldTemplate("permissionTemplate", IndexFieldTypeFactory::asString);
- context.bridge(Map.class, new MapValueBridge(userMetadataField.toReference()));
+ context.bridge(Map.class, new MapValueBridge());
}
@SuppressWarnings("rawtypes")
private static class MapValueBridge implements PropertyBridge<Map> {
private final IndexObjectFieldReference userMetadataFieldReference;
private MapValueBridge(IndexObjectFieldReference userMetadataFieldReference) {
this.userMetadataFieldReference = userMetadataFieldReference;
}
@Override
public void write(DocumentElement target, Map bridgedElement, PropertyBridgeWriteContext context) {
@SuppressWarnings("unchecked")
Map<String, Integer> permissions = (Map<String, Integer>) bridgedElement;
- DocumentElement indexedUserMetadata = target.addObject(userMetadataFieldReference);
for (Map.Entry<String, Integer> elto : permissions.entrySet()) {
if (elto.getValue() > 10) {
- indexedUserMetadata.addValue("myFieldName", elto.getKey());
+ target.addValue("myFieldName", elto.getKey());
}
}
}
}
}
schemaElement.fieldTemplate("permissionTemplate", f -> f.asString()
.searchable(Searchable.YES).projectable(Projectable.YES))
.multiValued();
But I’ve another doubt: in Lucene document I have now both fields: permission and myFieldName. And I’m not sure how I can avoid adding the permission field. If I change myFielName to permission an error is thrown, so the only way I see is defining the field this way:
I don’t even know what you’re trying to do, so it’s hard to give you advice
Why do use use both @PropertyBinding and @GenericField in the first place?
You do realize that the only effect of your @GenericField annotation is to index the map values in a permissions field? I’m not sure what’s the point of that.
Well, I’m still trying to understand this new version of Hibernate Search because has many, many changes. In v5.6 I was using:
@Field(index = Index.YES, analyze = Analyze.NO, store = Store.YES)
@FieldBridge(impl = MapFieldBridge.class)
protected Map<String, Integer> permissions = new HashMap<>();
I implemented a custom MapFieldBridge which added other values to the Lucene document, and worked pretty fine. It was much easier than now. I was trying to reproduce the same behaviour with the new version. I know right now is more search engine independent, but things are now much complex.
In short, I wanted to add values from the information stored in the Map (according to certain logic) using a give name, in this case “myFieldName” (as many as elements in the Map which matches a certain criteria).
Considering you’re only creating fields using your custom bridge here, In Hibernate Search 6 you most likely only need @PropertyBinding, not @GenericField.
It might not be obvious in Hibernate Search 5, but the @FieldBridge annotation does nothing on its own: it just configures the @Field annotation further.
To understand Hibernate Search 6 better, I suggest you have a look at the documentation.
The table in Bridge basics might help.
Things were already complex: hibernate Search 5 made assumptions that made things look simpler, but could often result in wrong behavior (missing reindexing, wrong field types) if you didn’t know better, or even limitations (no faceting for bridge-created fields, …).
So no, this “added” complexity is not just about Elasticsearch support.
By the way, is there any project with working code samples? I mean a simple Hibernate Search project where people can take a look and understand better how to use this new version improvements properly. I know the documentation is great but working samples would make it better.