带枚举字段的Hibernate SearchLucene范围查询不返回任何结果。

问题描述 投票:0回答:1

当使用Hibernate搜索时,有以下枚举字段。

public class UserSkill {
    @Enumerated
    @Field
    private UserSkillLevel level; // <- this is the field we're using on the ranged query
}

public class User { // <- this is the root class
    @IndexedEmbedded
    private Set<UserSkill> skills = new HashSet<>();
}

这是枚举。

public enum UserSkillLevel {
    JUNIOR,
    CONFIRMED,
    ADVANCED,
    EXPERT
}

当试图进行范围查询的时候。

var fullTextEntityManager = Search.getFullTextEntityManager(entityManager);

var queryBuilder = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity(User.class).get();

var bq = new BooleanQuery.Builder();

var q = queryBuilder.range().onField("skills.level").above(UserSkillLevel.ADVANCED).createQuery();
bq.add(q, BooleanClause.Occur.MUST);

return fullTextEntityManager.createFullTextQuery(bq.build(), User.class).getResultList();

问题是即使用户拥有高级或专家级的技能 也不会返回任何结果。

java hibernate enums lucene hibernate-search
1个回答
0
投票

枚举默认是以字符串为索引,所以你要求的范围实际上是 "每个技能等级的名称按字母顺序排列在'ADVANCED'一词之后".

因此,我希望这能符合 一切 而不是;也许你在更改映射后忘了重新索引你的数据?

不管怎么样... 如果你想把枚举作为序数索引,实现一个自定义桥接。

public class EnumAsIntegerBridge implements MetadataProvidingFieldBridge {
    @Override
    public void configureFieldMetadata(String name, FieldMetadataBuilder builder) {
        builder.field( name, FieldType.INTEGER );
    }

    @Override
    public void set(String name, Object value, Document document, LuceneOptions luceneOptions) {
        Enum<?> enum = (Enum<?>) value;

        if ( enum != null ) {
            luceneOptions.addNumericFieldToDocument( name, enum.ordinal(), document );
        }
    }
}

然后在你的映射中使用它

public class UserSkill {
    @Enumerated
    @Field(bridge = @FieldBridge(impl = EnumAsIntegerBridge.class))
    private UserSkillLevel level;
}

public class User {
    @IndexedEmbedded
    private Set<UserSkill> skills = new HashSet<>();
}

然后把序数而不是枚举传递给查询。

var q = queryBuilder.range().onField("skills.level").above(UserSkillLevel.ADVANCED.ordinal()).createQuery();
© www.soinside.com 2019 - 2024. All rights reserved.