Hibernate搜索:如何通过单独的列搜索全名
我有一个名为'Patient'的字符串字段名为'firstName','lastName'和'secondLastName'的实体(在西班牙语中,我们同时使用父亲和母亲姓氏)Hibernate搜索:如何通过单独的列搜索全名
我有一个文本框按照名称搜索患者的视图,其中用户可以按任何给定顺序键入任何内容:firstName,lastName,secondLastName或这些的组合。 例如,我的名字:
姓:毛, 名字:Ubilla, secondLastName:卡瓦哈尔,
如果我搜索“毛Ubilla卡瓦哈尔”,甚至“毛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”,它也不会返回任何内容。
但是,如果我更改查询只符合我的姓:如果我搜索
QueryBuilder qb = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(Patient.class).get();
Query luceneQuery = qb.keyword().onFields("firstName").matching(name).createQuery();
“毛”它的工作原理。
我在做什么错?有什么办法可以为3列定义组合索引吗?我应该以不同的方式构建我的查询吗? 请帮助我顺便说一句:( ,我使用Hibernate Search的4.5.1在休眠4.3和Java 1.7
您使用的是很旧版本的Hibernate搜索的,所以这是非常可能的,你正在运行到一个错误你应该考虑升级到至少Hibernate Search 5.6/Hibernate ORM 5.1,或者甚至更好的搜索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:查询应包含的子查询匹配元素
- 必须:查询必须包含子查询的匹配元素
- 必须:查询不得包含子查询的匹配元素
聚合类似于布尔逻辑的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();
谢谢获得!这就是我所做的,它工作正常。同时感谢您对升级到更新版本hibernate的建议。好像我很快就要做。 –