2017-10-04 204 views
0

我是hibernate lucene搜索的新手。从病房的几天开始,我正在使用特殊字符搜索关键字。我正在使用MultiFieldQueryParser进行精确的词组匹配以及布尔搜索。但在这个过程中,我无法使用“拥有1年以上的经验”等搜索关键字来获得搜索结果,如果我没有在搜索关键字周围添加任何引号,那么我会得到结果。所以我在执行lucene查询时观察到的是,它正在逃避特殊符号(+)。我正在使用StandardAnalyzer.class。我认为,如果我使用的是WhiteSpaceAnalyzer,它不会转义特殊字符,但它可能会影响布尔搜索,如+ java + php(即java和php),因为它可能会视为普通文本。所以请协助一些建议。如何在hibernate搜索中搜索特殊字符?

以下是我的代码片段:

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

回答

1

来控制这种影响的关键是确实在您选择使用的分析仪。正如您注意到的那样,标准分析仪将删除/忽略一些通常不使用的符号。

由于标准分析仪对于大多数英语自然语言都很好,但您也希望对待特殊符号,因此典型解决方案是将文本索引到多个字段,并为每个字段分配不同的Analyzer。然后,您可以生成针对两个字段的查询,并组合从两个字段中获得的分数。您甚至可以自定义每个领域的权重,并尝试使用不同的实现来获得各种效果。

但是,您可能想要考虑您期望找到的“1年以上”的具体示例。如果它匹配一个字符串“6年”? 然后你可能想要实现一个自定义分析器,它专门查找这样的模式并生成多个匹配令牌,如序列{“1年”,“2年”,“3年”,...}。这将会很有效,但只能匹配特定的术语序列,因此您可能希望从Lucene社区寻找更高级的扩展,因为您可以在其中插入更多扩展。

+0

@ Sanne.Tq为您的答复。在我的数据库中,我有一个名为profile title的字段。所以现在我想要得到的结果是我的搜索关键字匹配的地方。它不应该匹配字符串“6年“只有它必须得到匹配字符串”拥有1年以上的经验“。 – Satya