【问题标题】:how to search special characters in hibernate search?如何在休眠搜索中搜索特殊字符?
【发布时间】:2017-10-04 11:38:49
【问题描述】:

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

以下是我的sn-p:

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

【问题讨论】:

    标签: lucene hibernate-search


    【解决方案1】:

    控制此类效果的关键确实在您选择使用的分析器中。正如您所注意到的,标准分析器将删除/忽略一些通常不使用的符号。

    由于标准分析器适用于大多数英语自然语言,但您还想处理特殊符号,典型的解决方案是将文本索引到多个字段中,并为每个字段分配不同的 Analyzer。然后,您可以生成针对这两个字段的查询,并结合从这两个字段获得的分数。您甚至可以自定义每个字段应具有的权重,并尝试不同的Similarity 实现以获得各种效果。

    但是,对于“1 年以上”的具体示例,您可能需要考虑您期望它找到什么。它应该匹配字符串“6 年”吗? 然后,您可能想要实现一个自定义分析器,专门查找此类模式并生成多个匹配标记,如序列 {“1 year”、“2 years”、“3 years”、...}。这将是有效的,但只匹配特定的术语序列,所以也许你想从 Lucene 社区中寻找更高级的扩展,因为你可以在其中插入更多的扩展。

    【讨论】:

    • @Sanne.Tq 供您回复。在我的数据库中,我有一个名为配置文件标题的字段。所以现在我想在我的搜索关键字匹配的地方得到结果。它不应该得到匹配字符串“6 years”只有它必须得到匹配字符串“Having 1+ years of experience”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-22
    • 2018-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多