Reputation: 1068
I have a question regarding the possibility to enforce multiple constraints while performing a query with hibernate-search.
@Indexed
public class Contact{
//ommited fields
@IndexEmbedded
private List<Communication> communications;
//setters - getters
}
and the associated 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;
}
the enums
public static enum CommunicationUsage {
PRIVATE,
PROFESSIONNAL
}
public static enum CommunicationType{
PHONE,
EMAIL
}
An example query that I would need to accomplish is the following :
Find all contacts for which the communication type is "PHONE" and the CommunicationUsage is "PRIVATE" and the field value of the Communication class contains the string 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();
}
However I'm getting contacts that have a phone number matching the one provided but for different communication types and usages (such as PHONE and PROFESSIONAL)
So can this type of query be accomplished with hibernate-search or not?
Upvotes: 0
Views: 223
Reputation: 19129
At the moment this use case is not solvable with Hibernate Search with default indexing. The problem is that Hibernate Search flattens all data to be indexed (including the associations annotated via @IndexedEmbedded
) into a single Lucene Document
. In particular one looses in this case the "grouping" given by a single Communication
instance. If you have one Communication
instance with the type you are interested in and another instance with the value you are interested in, you will in your case get a match.
As a workaround you could provide a custom class bridge for the Communication
instance which somehow concatenates the values you are interested in. You would then try to write a query which targets this custom field.
Upvotes: 1