【问题标题】:Hibernate Search: how to query fields in parent class?Hibernate Search:如何查询父类中的字段?
【发布时间】:2020-07-02 08:10:53
【问题描述】:

我正在尝试使用 Hibernate Search 进行查询。 我想匹配从父类扩展的类中的字段(子类是@Indexed 类)。

这是我到目前为止所做的。

-Price 是索引类-

@Indexed
@Table(name = "price_products")
public class PriceEntity extends AbstractPrice {

    .....
    .....
    .....

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "productId")
    private ECommerceProductEntity parent;
    

    public ProductEntity getParent() {
        return parent;
    }

    public void setParent(ProductEntity parent) {
        this.parent = parent;
    }

    
}

-Products 是父类-

@Entity
@Indexed
@Table(name = "products")
public class ProductEntity extends AbstractProduct {


    @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    private List<PriceEntity> prices;

    /.others fields../


    @Field(termVector = TermVector.YES)
    @Size(max = 255)
    private String tags;

    /.others getter and setters../
    

    public String getTags() {
        return tags;
    }

    public void setTags(String tags) {
        this.tags = tags;
    }

    public List<PriceEntity> getPrices() {
        return prices;
    }

    public void setPrices(PriceEntity> prices) {
        this.prices = prices;
    }

    public void addPrice(ECommercePriceEntity price) {
        ...
    }

}

-AbstractProduct 由产品扩展-

@MappedSuperclass
public abstract class AbstractProduct {
    /.others fields../
    @NotBlank
    @Field(termVector = TermVector.YES)
    private String description;
    /getter end setters/
}

--查询--

FullTextEntityManager fullTextEntityManager
        = Search.getFullTextEntityManager(entityManager);
fullTextEntityManager.createIndexer().startAndWait();

FullTextEntityManager fullTextEntityManager2
        = Search.getFullTextEntityManager(entityManager);

QueryBuilder queryBuilder = fullTextEntityManager2.getSearchFactory()
        .buildQueryBuilder()
        .forEntity(PriceEntity.class)
        .get();

Query myQuery = queryBuilder
        .bool()
        .should(queryBuilder.keyword().withConstantScore()
                .onField("products.description").boostedTo(9l).matching(query)
                .createQuery())
        .should(queryBuilder.phrase().withConstantScore()
                .onField("products.description").boostedTo(5l).sentence(query)
                .createQuery())

        .should(queryBuilder.keyword().withConstantScore()
                .onField("products.tags").boostedTo(3l).matching(query)
                .createQuery())
        .should(queryBuilder.phrase().withConstantScore()
                .onField("products.tags").boostedTo(1l).sentence(query)
                .createQuery())
        .createQuery();

org.hibernate.search.jpa.FullTextQuery jpaQuery
        = fullTextEntityManager2.createFullTextQuery(myQuery, PriceEntity.class);
jpaQuery.setProjection("description");

List<PriceEntity> queryResults = jpaQuery.getResultList();

使用上面的代码,我得到以下错误

org.hibernate.search.exception.SearchException: Unable to find field products.description in ... 

如果 queryBuilder 的给定实体是 PriceEntity,如何通过字段“描述”(在 AbstractProduct 中)和 (ProductEntity) 中的标签进行查询?

提前致谢

【问题讨论】:

    标签: jquery hibernate elasticsearch querydsl hibernate-search


    【解决方案1】:

    你应该使用@IndexedEmbedded

    @Indexed
    @Table(name = "price_products")
    public class PriceEntity extends AbstractPrice {
    
        .....
    
        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "productId")
        @IndexedEmbedded // <= ADD THIS
        private ECommerceProductEntity parent;
    
    @Entity
    @Indexed
    @Table(name = "products")
    public class ProductEntity extends AbstractProduct {
    
    
        @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
        @ContainedIn // <= ADD THIS
        private List<PriceEntity> prices;
    

    然后重新索引所有数据。

    然后使用“父级”。如果要访问产品字段,请在查询价格时添加前缀:

    FullTextEntityManager fullTextEntityManager
            = Search.getFullTextEntityManager(entityManager);
    fullTextEntityManager.createIndexer().startAndWait();
    
    FullTextEntityManager fullTextEntityManager2
            = Search.getFullTextEntityManager(entityManager);
    
    QueryBuilder queryBuilder = fullTextEntityManager2.getSearchFactory()
            .buildQueryBuilder()
            .forEntity(PriceEntity.class)
            .get();
    
    Query myQuery = queryBuilder
            .bool()
            .should(queryBuilder.keyword().withConstantScore()
                    .onField("parent.description").boostedTo(9l).matching(query)
                    .createQuery())
            .should(queryBuilder.phrase().withConstantScore()
                    .onField("parent.description").boostedTo(5l).sentence(query)
                    .createQuery())
    
            .should(queryBuilder.keyword().withConstantScore()
                    .onField("parent.tags").boostedTo(3l).matching(query)
                    .createQuery())
            .should(queryBuilder.phrase().withConstantScore()
                    .onField("parent.tags").boostedTo(1l).sentence(query)
                    .createQuery())
            .createQuery();
    
    org.hibernate.search.jpa.FullTextQuery jpaQuery
            = fullTextEntityManager2.createFullTextQuery(myQuery, PriceEntity.class);
    jpaQuery.setProjection("parent.description");
    
    List<PriceEntity> queryResults = jpaQuery.getResultList();
    

    this section of the documentation

    【讨论】:

    • 我还在我的 AbstractProduct 类的字段注释中添加了 store= Store.YES
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-30
    相关资源
    最近更新 更多