如何在Hibernate Search中搜索带有通配符和空格的字段 [英] How to search fields with wildcard and spaces in Hibernate Search

查看:467
本文介绍了如何在Hibernate Search中搜索带有通配符和空格的字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个搜索框根据给定的输入在标题字段上执行搜索,所以用户推荐所有可用的标题都以插入的文本开始。它基于Lucene和Hibernate Search。它工作正常,直到输入空格。然后结果消失。例如,我希望学习H给我学习休眠作为结果。但是,这不会发生。你可以请教我,我应该用什么来代替。

查询生成器:
$ b

  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); (LearningGoal exGoal:existingGoals){
Term deletedTerm = new Term(id,String.valueOf(exGoal.getId()));

bQuery.add(新的TermQuery(ignoredTerm),BooleanClause.Occur.MUST_NOT);
}
@SuppressWarnings(unused)
org.hibernate.Query hibQuery = fullTextSession.createFullTextQuery(
query,LearningGoal.class);

Hibernate class
$ b $ (工厂= StandardTokenizerFactory.class),
filters = {
@TokenFilterDef(工厂= StandardFilterFactory.class),
@TokenFilterDef(factory = LowerCaseFilterFactory.class),
@TokenFilterDef(factory = StopFilterFactory.class,params = {
@Parameter(name =ignoreCase,value = true)})})
@Analyzer(definition =searchtokenanalyzer)
public class LearningGoal extends Node {


解决方案

我找到了解决此问题的解决方法。这个想法是标记输入字符串并删除停用词。对于最后一个标记,我使用关键字通配符创建了一个查询,对于之前创建的所有词,我创建了一个TermQuery。这里是完整的代码

  BooleanQuery bQuery = new BooleanQuery(); 
Session session = persistence.currentManager();
FullTextSession fullTextSession = Search.getFullTextSession(session);
Analyzer分析器= fullTextSession.getSearchFactory()。getAnalyzer(searchtokenanalyzer);
QueryParser parser = new QueryParser(Version.LUCENE_35,title,analyzer);
String [] tokenized = null;
尝试{
查询查询= parser.parse(searchString);
String clearedText = query.toString(title);
tokenized = cleanedText.split(\\s);

} catch(ParseException e){
// TODO自动生成的catch块
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(新的TermQuery(exactTerm),BooleanClause.Occur.MUST); (LearningGoal exGoal:existingGoals){
Term deletedTerm = new Term(id,String.valueOf(exGoal.getId()));
}
}

bQuery.add(新的TermQuery(ignoredTerm),BooleanClause.Occur.MUST_NOT);
}
org.hibernate.Query hibQuery = fullTextSession.createFullTextQuery(
bQuery,LearningGoal.class);


I have a search box that performs a search on title field based on the given input, so the user has recommended all available titles starting with the text inserted.It is based on Lucene and Hibernate Search. It works fine until space is entered. Then the result disapear. For example, I want "Learning H" to give me "Learning Hibernate" as the result. However, this doesn't happen. could you please advice me what should I use here instead.

Query Builder:

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 class:

@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 {

解决方案

I found workaround for this problem. The idea is to tokenize input string and remove stop words. For the last token I created a query using keyword wildcard, and for the all previous words I created a TermQuery. Here is the full code

    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);

这篇关于如何在Hibernate Search中搜索带有通配符和空格的字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆