我有一个搜索框,根据给定的输入在标题字段上执行搜索,因此用户建议所有可用的标题以插入的文本开头。它基于Lucene和Hibernate Search。它一直工作,直到输入空间。然后结果消失了。例如,我希望“学习H”给我“学习Hibernate”作为结果。但是,这不会发生。你能告诉我我应该在这里使用什么呢?
查询构建器:
QueryBuilder qBuilder = fullTextSession.getSearchFactory()
.buildQueryBuilder().forEntity(LearningGoal.class).get();
Query query = qBuilder.keyword().wildcard().onField("title")
.matching(searchString + "*").createQuery();
BooleanQuery bQuery = new BooleanQuery();
bQuery.add(query, BooleanClause.Occur.MUST);
for (LearningGoal exGoal : existingGoals) {
Term omittedTerm = new Term("id", String.valueOf(exGoal.getId()));
bQuery.add(new TermQuery(omittedTerm), BooleanClause.Occur.MUST_NOT);
}
@SuppressWarnings("unused")
org.hibernate.Query hibQuery = fullTextSession.createFullTextQuery(
query, LearningGoal.class);
Hibernate类:
@AnalyzerDef(name = "searchtokenanalyzer",tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class),
filters = {
@TokenFilterDef(factory = StandardFilterFactory.class),
@TokenFilterDef(factory = LowerCaseFilterFactory.class),
@TokenFilterDef(factory = StopFilterFactory.class,params = {
@Parameter(name = "ignoreCase", value = "true") }) })
@Analyzer(definition = "searchtokenanalyzer")
public class LearningGoal extends Node {
答案 0 :(得分:9)
我找到了解决此问题的方法。这个想法是标记输入字符串并删除停用词。对于最后一个令牌,我使用关键字通配符创建了一个查询,对于之前的所有单词,我创建了一个TermQuery。这是完整的代码
BooleanQuery bQuery = new BooleanQuery();
Session session = persistence.currentManager();
FullTextSession fullTextSession = Search.getFullTextSession(session);
Analyzer analyzer = fullTextSession.getSearchFactory().getAnalyzer("searchtokenanalyzer");
QueryParser parser = new QueryParser(Version.LUCENE_35, "title", analyzer);
String[] tokenized=null;
try {
Query query= parser.parse(searchString);
String cleanedText=query.toString("title");
tokenized = cleanedText.split("\\s");
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
QueryBuilder qBuilder = fullTextSession.getSearchFactory()
.buildQueryBuilder().forEntity(LearningGoal.class).get();
for(int i=0;i<tokenized.length;i++){
if(i==(tokenized.length-1)){
Query query = qBuilder.keyword().wildcard().onField("title")
.matching(tokenized[i] + "*").createQuery();
bQuery.add(query, BooleanClause.Occur.MUST);
}else{
Term exactTerm = new Term("title", tokenized[i]);
bQuery.add(new TermQuery(exactTerm), BooleanClause.Occur.MUST);
}
}
for (LearningGoal exGoal : existingGoals) {
Term omittedTerm = new Term("id", String.valueOf(exGoal.getId()));
bQuery.add(new TermQuery(omittedTerm), BooleanClause.Occur.MUST_NOT);
}
org.hibernate.Query hibQuery = fullTextSession.createFullTextQuery(
bQuery, LearningGoal.class);
答案 1 :(得分:-2)
SQL使用与任何终端不同的通配符。在SQL '%'
中替换零个或多个任何字符(在您使用'*'
的终端中),而下划线'_'
恰好替换一个字符(在您使用的终端中{{1}而不是)。 Hibernate不会翻译通配符。
因此,在第二行中,您必须将'?'
替换为
matching(searchString + "*")