Hibernate搜索:如何在单独的列上搜索全名

我有一个名为'Patient'的字符串字段名为'firstName','lastName'和'secondLastName'的实体(在西班牙语中,我们同时使用父亲和母亲姓名)

我有一个带有文本框的视图来按名称搜索患者,用户可以按照任何给定的顺序输入任何内容:名字,姓氏,次要姓氏或这些的组合。 例如,用我的名字:

名字:Mauricio,姓氏:Ubilla,secondLastName:Carvajal,

如果我搜索“Mauricio Ubilla Carvajal”或甚至是“Mauricio Ubilla”,我希望在结果列表中排名第一。 问题是:

1-如何定义这3个字段的索引? 我做了以下几点:

@Indexed   
class Patient {
    ...
    @Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
    protected String firstName = new String();
    @Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
    protected String lastName = new String();
    @Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
    protected String secondLastName = new String();
    ...
}

2-我应该如何构建查询? 我这样做了:

QueryBuilder qb = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(Patient.class).get();        
Query luceneQuery = qb.keyword().onFields("firstName", "lastName", "secondLastName").matching(name).createQuery();

但是,这不适合我。 它没有抛出任何异常,只是它没有返回任何东西。 即使我只搜索“Mauricio”,它也不会返回任何内容。

但是,如果我只改变查询来匹配我的firstName:

QueryBuilder qb = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(Patient.class).get();        
Query luceneQuery = qb.keyword().onFields("firstName").matching(name).createQuery();

如果我搜索“Mauricio”,它会起作用。

我究竟做错了什么? 有没有办法为3列定义组合索引? 我应该以不同的方式构建我的查询吗? 请帮助我:(顺便说一句,我使用Hibernate搜索4.5.1超过Hibernate 4.3和Java 1.7


你正在使用一个非常老的Hibernate Search版本,所以你很可能会遇到一个已经在更新版本中解决的bug。 你应该真的考虑升级到至少Hibernate Search 5.6 / Hibernate ORM 5.1,或者甚至更好地升级到Search 5.8 / ORM 5.2(需要Java 8)。

如果你不能......另一个常见的解决方案是索引一个瞬时属性,其内容是连接名称:

@Indexed   
class Patient {
    ...
    @Field
    protected String firstName = "";
    @Field
    protected String lastName = "";
    @Field
    protected String secondLastName = "";
    ...
    @javax.persistence.Transient
    @Field
    public String getFullName() {
        // TODO null safety
        return firstName + " " + lastName + " " + secondLastName;
    }
    ...
}

然后查询这个fullName

QueryBuilder qb = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(Patient.class).get();        
Query luceneQuery = qb.keyword().onFields("fullName").matching(name).createQuery();

请注意,与初始解决方案相反,这会对性能产生负面影响,因为对@Transient字段进行索引会禁用某些优化。 但至少它应该工作。


回答你的第二个问题。 您可以使用短语作为句子而不是关键字进行搜索。

Hibernate Search还支持使用各种策略来组合查询:

-SHOULD:查询应该包含子查询的匹配元素

-MUST:查询必须包含子查询的匹配元素

- 不必:查询不得包含子查询的匹配元素

聚合类似于布尔逻辑的AND,OR和NOT。

    Query combinedQuery = queryBuilder
   .bool()

   .must(queryBuilder.phrase()
   .onField("productName).sentence("samsung galaxy s8")
   .createQuery())

   .must(queryBuilder.keyword()
   .onField("productCategory").matching("smartphone")
   .createQuery())

   .createQuery();


    // wrap Lucene query in an Hibernate Query object
    org.hibernate.search.jpa.FullTextQuery jpaQuery =
    fullTextEntityManager.createFullTextQuery(combinedQuery, Product.class);

    // execute search and return results (sorted by relevance as default)
    @SuppressWarnings("unchecked")
    List<Product> results = jpaQuery.getResultList();

参考http://www.baeldung.com/hibernate-search

链接地址: http://www.djcxy.com/p/37101.html

上一篇: Hibernate Search: how to search a full name over separate columns

下一篇: combining 2 or more properties in Hibernate Restrictions criteria query