java - 为多个字段构建 Lucene 查询

标签 java lucene

我有一个具有搜索功能的 spring MVC 应用程序。

Flow: UI > CONTROLLER > BL > DATA > SOLR

允许用户使用多个字段搜索某些内容,例如按名称或部门搜索。业务层需要有一个接受字符串并为 SOLR 构建适当的 Lucene 查询的 Lucene 查询构建器。

我的 Controller :

@GetMapping(params = "name")
public Page<User> findUserByName(@RequestParam("name") final String name) {
    return userService.findUserByName(name);
}

@GetMapping(params = "department")
public Page<User> findUserByDepartment(@RequestParam final String department) {
    return userService.findUserByFulltext(department);
}

虚拟查询生成器

public String searchByNameQuery(final String name) {
    return "nm:" + name;
}
public String searchByDepartmentQuery(final String department) {
    return "dpt:" + department;
}

现在这个虚拟查询构建器不支持通配符或任何其他变体。我正在浏览 Apache Lucene 查询 API(也将 lucene core-7.7.1 添加到项目中)和一堆教授如何使用不同类型的查询实现(TermQuery、PhraseQuery、BooleanQuery 等)的文章,但它没有完全有道理。最后,我仍然手动构建查询。

有人可以帮助我展示如何拥有合适的 Lucene 查询生成器类吗?

我需要使用精确的短语和通配符为这些类型的文本生成查询

(exact)Search by name: Ohio State University
Search by name: *State
Search by name: Ohio*University
Search by name: Ohio State*
Search by Department:Computer Science Dept
Search by Department: *Science

组合查询:

nm:"Ohio State University" AND dpt:"Computer Science"

最佳答案

boolean 查询构建器可以像这样用于例如:

new BooleanQuery.Builder().add(query1, BooleanClause.OCCUR.MUST)
                              .add(query2, BooleanClause.OCCUR.MUST_NOT)
                              .build();

如果你更喜欢复杂的聚合,对于字段和搜索字符串——你可以写类似的东西——

public class CustomBooleanQueryBuilder {

    public Map<BooleanClause.Occur, List<Query>> getClauseQueryMap() {
        return clauseQueryMap;
    }

    private final Map<BooleanClause.Occur, List<Query>> clauseQueryMap = new HashMap();

    public static void main(String args[]) throws ParseException {
        CustomBooleanQueryBuilder queryBuilder = new CustomBooleanQueryBuilder();

        final Query regExpQuery = new RegexpQuery(new Term("nm", "Hello\\sWorld"));
        queryBuilder.addUpdateQueryMap(regExpQuery, BooleanClause.Occur.MUST);

        final Query wildcardQuery = new WildcardQuery(new Term("nm", "Hello?World"));
        queryBuilder.addUpdateQueryMap(wildcardQuery, BooleanClause.Occur.MUST_NOT);

        System.out.println(queryBuilder.aggregateQueryBoolean(queryBuilder.clauseQueryMap));

    }



    private String aggregateQueryBoolean(final Map<BooleanClause.Occur, List<Query>> clauseQueryMap) {
        final BooleanQuery.Builder booleanQueryBuilder = new BooleanQuery.Builder();
        clauseQueryMap.forEach((booleanClause, queryList) -> queryList.forEach((query) -> booleanQueryBuilder.add(query, booleanClause)));
        return booleanQueryBuilder.build().toString();
    }

    private void addUpdateQueryMap(final Query query, final BooleanClause.Occur booleanOccur) {
        if (clauseQueryMap.containsKey(booleanOccur)) {
            clauseQueryMap.get(booleanOccur).add(query);
        } else {
            final List<Query> queryList = new ArrayList();
            queryList.add(query);
            clauseQueryMap.put(booleanOccur, queryList);
        }
    }
}

关于java - 为多个字段构建 Lucene 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55151876/

相关文章:

java - git/GitHub 属性配置

java - Swagger 根据枚举值生成子类型

java - 自签名 (jdk 7u45) Applet 在 Firefox 和 chrome 中通过 SSL 运行时出现 NullPointerException

java - 将 Alfresco 社区版 5.0 升级到 5.1 搜索功能不起作用?

java - 卢塞恩 : how to get a line of occurence of query

java - 无法从服务器应用程序使用 ssl 连接 mongodb

java - 远程 OSGI 服务调用

java - Lucene查询语法中AND和+有什么区别

java - 使用 Lucene 搜索有多少结果?

lucene - 分页Lucene的搜索结果