Hibernate Search Tuple Queries -
i have entity message one-to-many relation entity header. how can create tuple based search query
(message.headerkey="foo" , message.headervalue="123") , (message.headerkey="bar" , message.headervalue="456")
my current logic match when swap header values in search criteria
(message.headerkey="foo" , message.headervalue="456") , (message.headerkey="bar" , message.headervalue="123")
how can tuple based query using hibernate search api?
this message entity:
@entity @table(name="message") @indexed public class messageentity implements serializable { @id @generatedvalue(strategy=generationtype.auto) @column(name="id") private long id; @column(name="message_timestamp") private date timestamp; @column(name="payload") @field(index=index.yes, analyze=analyze.yes, store=store.no) private string payload; @onetomany(cascade = { cascadetype.persist, cascadetype.merge }, mappedby = "message") @indexedembedded private list<headerentity> headers; // getters , setters }
this header entity:
@entity @table(name="header") public class headerentity implements serializable { @id @generatedvalue(strategy=generationtype.identity) private long id; @column(name="header_key") @field(index=index.yes, analyze=analyze.yes, store=store.no) private string headerkey; @column(name="header_value") field(index=index.yes, analyze=analyze.yes, store=store.no) private string headervalue; @manytoone(cascade=cascadetype.all) @joincolumn(name="message_id") private messageentity message; // getters , setters }
this search logic:
public list<messageentity> search(header[] headers) { fulltextentitymanager fulltextentitymanager = org.hibernate.search.jpa.search.getfulltextentitymanager(mgr); querybuilder qb = fulltextentitymanager.getsearchfactory().buildquerybuilder().forentity(messageentity.class).get(); termmatchingcontext onfieldkey = qb.keyword().onfield("headers.headerkey"); termmatchingcontext onfieldvalue = qb.keyword().onfield("headers.headervalue"); booleanjunction<booleanjunction> bool = qb.bool(); org.apache.lucene.search.query query = null; (header header : headers) { bool.must(onfieldkey.matching(header.getkey()).createquery()); bool.must(onfieldvalue.matching(header.getvalue()).createquery()); } query = bool.createquery(); fulltextquery persistencequery = fulltextentitymanager.createfulltextquery(query, messageentity.class); persistencequery.setmaxresults(10); return persistencequery.getresultlist(); }
your approach indeed not work. problem lucene flat data structure, in particular associations (embedded entities) "added" lucene document
of owning entity. in case messageentity
document contain 2 fields per headerkey
respectively headervalue
. once "foo" , "bar" value and56" values. once "123" , "456" values. there no notion 2 of these values acutally pair.
one potential solution create unique field/value pair. using custom class bridge create "keyvaluefield" containing header key , value concatenated value. in query target field using concatenated query parameters.
Comments
Post a Comment