我正在使用Hibernate Search和Apache Lucene的混合。我所做的事情應該是相當直接和容易的,但我無法實現我的目標。如何強制兩個查詢的組合必須在Lucene中?
我有我要查詢的字段的字符串(短語)的列表。該字段可以包含任何這些字符串。在每個領域之間,只有其中一個必須完全匹配。
在MySQL中,它看起來像這樣
select * from movies where (genres = 'name' or genres = 'name2') OR (actors = 'name' or actors = 'name2)' AND (actors = 'name' or actors = 'name2)
因此,如果一部電影至少包含1個流派給出1級給出的演員或2個演員,條件將滿足。現在在Lucene中,我首先構建一個布爾查詢,將所有可能的角色與Occur.SHOULD
結合在一起。然後,我構建了另一個布爾查詢,將前一個布爾查詢與另一個布爾查詢(例如,包含所有類型)結合起來。
最後,我做同樣的兩次,這兩個BooleanQueries與Occur.MUST
添加到新的一個,兩個。然而,如果我的條件中只有一個條件滿足,我至少得到了2個結果。我該如何解決這個問題?
private BooleanQuery getMatchQuery(List<String> list, String field) {
BooleanQuery bq = new BooleanQuery();
QueryBuilder qb = getFullTextEntityManager().getSearchFactory().buildQueryBuilder().forEntity(Movie.class).get();
for (String string : list) {
bq.add(qb.phrase().onField(field).sentence(string).createQuery(), Occur.SHOULD);
}
return bq;
}
private BooleanQuery getParamMatches(MovieDto dto, boolean genres){
BooleanQuery bq = new BooleanQuery();
bq.add(getMatchQuery(dto.getActors(), "actors"), Occur.SHOULD);
bq.add(getMatchQuery(dto.getDirectors(), "directors"), Occur.SHOULD);
bq.add(getMatchQuery(dto.getWriters(), "writers"), Occur.SHOULD);
if(genres){
bq.add(getMatchQuery(dto.getGenres(), "genres"), Occur.SHOULD);
}
return bq;
}
public List<Movie> test(MovieDto dto){
QueryBuilder qb = getFullTextEntityManager().getSearchFactory().buildQueryBuilder().forEntity(Movie.class).get();
log.info(getMatches(dto.getActors()));
BooleanQuery bq = new BooleanQuery();
bq.add(getParamMatches(dto, true), Occur.MUST);
bq.add(getParamMatches(dto, false), Occur.MUST);
javax.persistence.Query query = getFullTextEntityManager().createFullTextQuery(bq, Movie.class);
List<Movie> result = query.getResultList();
return result;
}
這是我按照上述方法進行操作的順序。雖然呼叫從下到上完成。結果查詢是這一個:
+((actors:"marlon brando" actors:"al pacino" actors:"james caan" actors:"richard s castellano")
(directors:"francis ford coppola") (writers:"mario puzo screenplay" writers:"francis ford coppola screenplay" writers:"mario puzo novel")
(genres:crime genres:drama))
+((actors:"marlon brando" actors:"al pacino" actors:"james caan" actors:"richard s castellano")
(directors:"francis ford coppola") (writers:"mario puzo screenplay" writers:"francis ford coppola screenplay" writers:"mario puzo novel"))
所以,我怎麼去讓這兩個條件結合強制性的,所以我不會接受,其中只有一個演員的結果,導演等存在?我希望至少有兩個參數匹配,每個查詢一個。
我才意識到在詳細打字出這一切,那我可能已經做正確,但它並不完全適用於我的情況,因爲QUERY1和QUERY2既可以匹配相同的演員和整個事情會是真的。任何人都可以證實這一點?如果有人對我的問題有一個解決方案,我沒有正確識別,那甚至會更好。 – Schaka