我正在使用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