使用 hibernate-search 在嵌入式实体中实施多个约束
Enforce multiple constraints in embedded entities with hibernate-search
我有一个关于在使用 hibernate-search 执行查询时强制执行多个约束的可能性的问题。
@Indexed
public class Contact{
//ommited fields
@IndexEmbedded
private List<Communication> communications;
//setters - getters
}
和关联的 class
@Indexed
public class Communication{
@Field(analyze = Analyze.YES, store = Store.YES)
private String value;
@Field(analyze = Analyze.YES, store = Store.YES)
private CommunicationType communicationType;
@Field(analyze = Analyze.YES, store = Store.YES)
private CommunicationUsage communicationUsage;
}
枚举
public static enum CommunicationUsage {
PRIVATE,
PROFESSIONNAL
}
public static enum CommunicationType{
PHONE,
EMAIL
}
我需要完成的示例查询如下:
查找通信类型为"PHONE"、CommunicationUsage 为"PRIVATE" 且Communication class 的字段值包含字符串999
的所有联系人
public List<Contact> search(){
FullTextEntityManager fullTextEntityManager =
Search.getFullTextEntityManager(em);
QueryBuilder qb = fullTextEntityManager.getSearchFactory()
.buildQueryBuilder().forEntity(Contact.class).get();
org.apache.lucene.search.Query luceneQuery =
qb.bool() .must(qb.keyword().wildcard().onField("communications.value").matching("*99999*").createQuery()) .must(qb.keyword().onField("communications.type").ignoreFieldBridge().matching("phone").createQuery()) .must(qb.keyword().onField("communications.usage").ignoreFieldBridge().matching("private").createQuery())
.createQuery();
org.hibernate.search.jpa.FullTextQuery jpaQuery =
fullTextEntityManager.createFullTextQuery(luceneQuery, Contact.class);
List result = jpaQuery.getResultList();
}
然而,我得到的联系人的 phone 号码与提供的号码匹配,但用于不同的通信类型和用途(例如 PHONE 和专业)
那么这种类型的查询可以用hibernate-search来完成吗?
目前,使用默认索引的 Hibernate Search 无法解决此用例。问题在于 Hibernate Search 将所有要索引的数据(包括通过 @IndexedEmbedded
注释的关联)扁平化为单个 Lucene Document
。特别是在这种情况下,一个 "grouping" 由单个 Communication
实例给出。如果您有一个 Communication
实例具有您感兴趣的类型,另一个实例具有您感兴趣的值,那么您将获得匹配。
作为解决方法,您可以为 Communication
实例提供一个自定义 class 桥,它以某种方式连接您感兴趣的值。然后您将尝试编写一个针对此自定义字段的查询.
我有一个关于在使用 hibernate-search 执行查询时强制执行多个约束的可能性的问题。
@Indexed
public class Contact{
//ommited fields
@IndexEmbedded
private List<Communication> communications;
//setters - getters
}
和关联的 class
@Indexed
public class Communication{
@Field(analyze = Analyze.YES, store = Store.YES)
private String value;
@Field(analyze = Analyze.YES, store = Store.YES)
private CommunicationType communicationType;
@Field(analyze = Analyze.YES, store = Store.YES)
private CommunicationUsage communicationUsage;
}
枚举
public static enum CommunicationUsage {
PRIVATE,
PROFESSIONNAL
}
public static enum CommunicationType{
PHONE,
EMAIL
}
我需要完成的示例查询如下:
查找通信类型为"PHONE"、CommunicationUsage 为"PRIVATE" 且Communication class 的字段值包含字符串999
的所有联系人 public List<Contact> search(){
FullTextEntityManager fullTextEntityManager =
Search.getFullTextEntityManager(em);
QueryBuilder qb = fullTextEntityManager.getSearchFactory()
.buildQueryBuilder().forEntity(Contact.class).get();
org.apache.lucene.search.Query luceneQuery =
qb.bool() .must(qb.keyword().wildcard().onField("communications.value").matching("*99999*").createQuery()) .must(qb.keyword().onField("communications.type").ignoreFieldBridge().matching("phone").createQuery()) .must(qb.keyword().onField("communications.usage").ignoreFieldBridge().matching("private").createQuery())
.createQuery();
org.hibernate.search.jpa.FullTextQuery jpaQuery =
fullTextEntityManager.createFullTextQuery(luceneQuery, Contact.class);
List result = jpaQuery.getResultList();
}
然而,我得到的联系人的 phone 号码与提供的号码匹配,但用于不同的通信类型和用途(例如 PHONE 和专业)
那么这种类型的查询可以用hibernate-search来完成吗?
目前,使用默认索引的 Hibernate Search 无法解决此用例。问题在于 Hibernate Search 将所有要索引的数据(包括通过 @IndexedEmbedded
注释的关联)扁平化为单个 Lucene Document
。特别是在这种情况下,一个 "grouping" 由单个 Communication
实例给出。如果您有一个 Communication
实例具有您感兴趣的类型,另一个实例具有您感兴趣的值,那么您将获得匹配。
作为解决方法,您可以为 Communication
实例提供一个自定义 class 桥,它以某种方式连接您感兴趣的值。然后您将尝试编写一个针对此自定义字段的查询.