根据索引检查实体的可搜索字段

时间:2019-04-18 15:57:45

标签: hibernate-search

我有一个定义如下的实体。

public class Deal {
    @Id
    @DocumentId
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Field
    @Column(name = "NAME")
    private String name;

    @Field
    @Column(name = "ADVERTISER_NAME")
    private String advertiserName;

    @Field
    @Column(name = "BRAND_NAME")
    private String brandName;

    //other fields and getters/setters omitted for brevity
}

如果我想搜索所有可搜索字段,则可以执行以下操作,该操作演示了onField,onFields和andFields的用法。


Query luceneQuery1 = mythQB
    .simpleQueryString()
    .onFields("name", "history", "description")
    .matching("teststring")
    .createQuery();


Query luceneQuery2 = mythQB
    .simpleQueryString()
    .onField("name")
        .boostedTo(5f)
    .andFields("advertiserName", "brandName")
        .boostedTo(2f)
    .withAndAsDefaultOperator()
    .matching("teststring")
    .createQuery();

例如,如果我将Index.NO添加到@Field(使实体字段不可搜索),例如,将brandName的注释更改为@Field(index = Index.NO),那么我现在只有两个可搜索字段:name和AdvertiserName(如果我们不考虑ID)。在这种情况下,上面的示例查询将引发运行时异常,因为它尝试搜索不可搜索的brandName。

我已经尝试过以下类似的操作,以根据字段是否具有注释来动态获取可搜索字段的完整列表。但是,如果索引为Index.NO,这将无法工作。

我的问题是,有没有一种方法可以根据实际的索引值动态获取可搜索字段的完整列表?

    protected String[] getSearchableFields() {
        List<String> fields = Lists.newArrayList();
        Class<?> c = clazz;
        while (c != null) {
            for (Field field : c.getDeclaredFields()) {
                if (field.isAnnotationPresent(org.hibernate.search.annotations.Field.class) 
                    || field.isAnnotationPresent(org.hibernate.search.annotations.Fields.class)) {

                    if (field.getType().isAssignableFrom(String.class)) {
                        fields.add(field.getName());
                    }
                }
            }
            c = c.getSuperclass();
        }
        return fields.toArray(new String[fields.size()]);
    }

1 个答案:

答案 0 :(得分:1)

Hibernate Search中有一个元数据API。

FullTextSession ftSession = ...;
IndexedTypeDescriptor indexedType = ftSession.getSessionFactory().getIndexedTypeDescriptor(clazz);
for (PropertyDescriptor property : indexedType.getIndexedProperties()) {
    for (FieldDescriptor field : property.getIndexedFields()) {
        if (field.getIndex() == Index.YES) {
            // do something
        }
    }
}

有关更多信息,请参见this section of the reference documentation

有一些限制,例如无法“看到”自定义桥所贡献的额外字段。但除此之外,效果很好。