我是hibernate lucene搜索的新手。从病房的几天开始,我正在研究带有特殊字符的搜索关键字。我正在使用 MultiFieldQueryParser 进行精确的词组匹配以及布尔搜索。但在这个过程中,我无法通过搜索关键字获得结果,例如“拥有1年多的经验”,如果我没有在搜索关键字周围添加任何引号,那么我就会得到结果。所以我在执行lucene查询时观察到的是,它是转义特殊符号(+)。我正在使用StandardAnalyzer.class。我想,如果我使用的是WhiteSpaceAnalyzer,它将无法转义特殊字符,但它可能会影响布尔搜索,如+ java + php(即java和php),因为它可能会视为普通文本。所以请提供一些建议。
以下是我的代码:
Session session = getSession();
FullTextSession fullTextSession = Search.getFullTextSession(session);
MultiFieldQueryParser parser = new MultiFieldQueryParser(new String[] { "student.skills.skill",
"studentProfileSummary.profileTitle", "studentProfileSummary.currentDesignation" },
new StandardAnalyzer());
parser.setDefaultOperator(Operator.OR);
org.apache.lucene.search.Query luceneQuery = null;
QueryBuilder qb = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(Student.class).get();
BooleanQuery boolQuery = new BooleanQuery();
if (StringUtils.isEmpty(zipcode) != true && StringUtils.isBlank(zipcode) != true) {
boolQuery.add(
qb.keyword().onField("personal.locations.postalCode").matching(zipcode).createQuery(),
BooleanClause.Occur.MUST);
}
if (StringUtils.isEmpty(query) != true && StringUtils.isBlank(query) != true) {
try {
luceneQuery = parser.parse(query.toUpperCase());
} catch (ParseException e) {
luceneQuery = parser.parse(parser.escape(query.toUpperCase()));
}
boolQuery.add(luceneQuery, BooleanClause.Occur.MUST);
}
boolQuery.add(qb.keyword().onField("vStatus").matching(1).createQuery(), BooleanClause.Occur.MUST);
boolQuery.add(qb.keyword().onField("status").matching(1).createQuery(), BooleanClause.Occur.MUST);
boolQuery.add(qb.range().onField("studentProfileSummary.profilePercentage").from(80).to(100).createQuery(),
BooleanClause.Occur.MUST);
FullTextQuery createFullTextQuery = fullTextSession.createFullTextQuery(boolQuery, Student.class);
createFullTextQuery.setProjection("id", "studentProfileSummary.profileTitle", "firstName","lastName");
if (isEmptyFilter == false) {
createFullTextQuery.setFirstResult((int) pageNumber);
createFullTextQuery.setMaxResults((int) end);
}
return createFullTextQuery.list();
答案 0 :(得分:1)
控制此类效果的关键在于您选择使用的分析仪。正如您所注意到的那样,标准分析器将删除/忽略一些符号,因为它们通常不被使用。
由于标准分析器适用于大多数英语自然语言,但您想要处理特殊符号,典型的解决方案是将文本索引到多个字段,并为每个字段分配不同的Analyzer
。然后,您可以生成针对这两个字段的查询,并合并从两个字段获取的分数。您甚至可以自定义每个字段所具有的权重,并尝试使用不同的Similarity
实现来获得各种效果。
但是,不是你的“1年以上”的具体例子,你可能想要考虑你期望它找到什么。它应该匹配“6年”的字符串吗? 然后你可能想要实现一个自定义分析器,专门寻找这样的模式并生成多个匹配的令牌,如序列{“1年”,“2年”,“3年”,......}。这将是有效的,但只能匹配特定的术语序列,所以您可能希望从Lucene社区中寻找更高级的扩展,因为您可以在其中插入更多的扩展。