0

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

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),现在我只有两个可搜索字段:名称和广告商名称,如果我们不考虑id。在这种情况下,上面的示例查询将引发运行时异常,因为它尝试搜索不可搜索的品牌名称。

我尝试了类似以下的方法来根据字段是否具有注释来动态获取可搜索字段的完整列表。但是,如果索引是 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()]);
    }
4

1 回答 1

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
        }
    }
}

有关详细信息,请参阅参考文档的此部分

有一些限制,比如无法“看到”自定义桥提供的额外字段。但除此之外它运作良好。

于 2019-04-18T16:22:05.020 回答