uncaught_exception
uncaught_exception

Reputation: 1078

Hibernate Search Dynamically Determine Indexed Fields

I have an entity as shown below; the field to column mapping is being performed using XML so isn't visible here. I am using Hibernate search to index certain fields of certain entities as and when they are modified.

@Indexed
public class DataObject extends AbstractEntity {    

    @DocumentId
    private Long id;
    ...

    @Field
    private String summary;

    @Field
    private String description;

    private Map<String, Object> extendedProperties;
}

Now, everything works fine for the properties I have enabled for search using annotations.

I use the extendedProperties to allow dynamic properties to be added to a DataObject. These properties are mapped to "jsonb" type in PostgreSQL 9.4 and are stored as a JSON object. The extended properties are configurable and the configuration will have a property indexed that will determine if the property should be indexed.

What I want to do is add the searchable properties and their values to the EntityIndexBinding (I reached here after debugging the Hibernate code) before the entity is indexed upon an insert or update. Is there a way to do this and if so how?

Upvotes: 1

Views: 959

Answers (1)

uncaught_exception
uncaught_exception

Reputation: 1078

So far this seems to work ...

@Indexed
public class DataObject extends AbstractEntity {    

    @DocumentId
    private Long id;
    ...

    @Field
    private String summary;

    @Field
    private String description;

    @Column(name = "extendedProperties")
    @Type(type = "StringJsonObject") // to map to PostgreSQL jsonb  
    @Field(name="", bridge = @FieldBridge( impl = ExtendedPropertyBridge.class))
    private Map<String, Object> extendedProperties;
}

public class ExtendedPropertyBridge implements FieldBridge {    

    @Override
    public void set(String name, Object value, Document document,
            LuceneOptions luceneOptions) {

        @SuppressWarnings("unchecked")
        Map<String, Object> map = (Map<String, Object>)value;
        for (String key : map.keySet()) {
            //TODO validate if key is searchable
            String val = map.get(key).toString();
            if (val != null) {
                luceneOptions.addFieldToDocument(key, val, document);
            }
        }
    }   
}

While querying I have to use the ignoreFieldBridge() option.

Reference

https://docs.jboss.org/hibernate/search/5.2/reference/en-US/html/search-mapping.html#search-mapping-bridge

Upvotes: 1

Related Questions