Loading [MathJax]/jax/input/TeX/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >将嵌套Hibernate搜索5谓词转换为Hibernate搜索6

将嵌套Hibernate搜索5谓词转换为Hibernate搜索6
EN

Stack Overflow用户
提问于 2022-03-14 08:06:31
回答 1查看 409关注 0票数 0

在将应用程序从Hibernate搜索5转换为6的过程中,我阅读了很多文档,特别是关于如何在简单场景中转换查询DSL的单个/#查询-引用,但是如何将谓词嵌套到其他嵌套谓词中,然后在更大的查询中将它们与其他谓词结合起来呢?

在Hibernate搜索5中,我们将使用queryBuilder.bool()创建一个BooleanJunction,然后通过在bool上调用createQuery来在另一个BooleanJunction中添加它,并反复创建嵌套谓词查询。

我所讨论的转换代码类型的示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    BooleanJunction vendorNameBool = queryBuilder.bool();
    BooleanJunction nameBool = queryBuilder.bool();
    
    nameBool.must(
        qb.keyword()
            .onField(CompanyName)
            .matching(nameToken1)
            .createQuery()
    );
    
    nameBool.must(
        qb.keyword()
            .onField(CompanyName)
            .matching(nameToken2)
            .createQuery()
    );

    vendorNameBool.should(nameBool.createQuery);
    
    // do vendorNameBool.should(...) for as many vendor Names that exist, then createQuery 
    probableVendorNamesQuery = vendorNameBool.createQuery();
    
    // creating a number of Queries from various bools and then combining them:
    Query taxIdOrVendorNameOrPhoneNumberQuery = qb.bool()
        .should(probableVendorNamesQuery)
        .should(taxIdQuery)
        .should(phoneNumberQuery)
        .createQuery();
        
    //and add to the final BooleanQuery along with other Query pieces
    
    Query idQuery = getIdQuery();
    Query fileIdQuery = getFileIdQuery();
    
    BooleanQuery.Builder theQuery = new BooleanQuery.Builder();
    theQuery.add(taxIdOrVendorNameOrPhoneNumberQuery, MUST);
    theQuery.add(fileIdQuery, MUST);    
    theQuery.add(idQuery, MUST_NOT);    
    
    BooleanQuery probableQuery = theQuery.build();
     
    // add some projections and execute query

大多数HS6代码示例都以lambda形式出现。有一节这里提供了一个创建非lamba谓词的简单示例,并将它们添加到list中,但是,例如,您将如何将谓词列表添加到外部must子句中,然后将该must子句以及另一个must子句添加到外部“必须”子句,等等。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-03-14 23:38:44

就我个人而言,我只需要使用lambda语法并嵌套第二个lambda。修改迁移指南中的示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 MySearchParameters searchParameters = ...;
 SearchSession session = Search.session( entityManager );
 List<Book> hits = searchSession.search( Book.class )
         .where( f -> f.bool( b -> {
             b.must( f.matchAll() );
             if ( searchParameters.getSearchTerms() != null ) {
                 b.must( f.simpleQueryString().fields( "title", "description" )
                         .matching( searchParameters.getSearchTerms() )
                         .defaultOperator( BooleanOperator.AND ) );
             }
             // ...
             // BEGIN NEW CODE
             SomeComplexParameter complexParam = searchParameters.getSomeComplexParameter();
             if ( complexParam != null ) {
                 b.must( f.bool( b2 -> {
                     b2.should( f.match().field( "someField1" )
                         .matching( complexParam.getSomeField1() ) );
                     b2.should( f.match().field( "someField2" )
                         .matching( complexParam.getSomeField2() ) );
                 } ) );
             }
             // END NEW CODE
         } ) )
         .fetchHits( params.getPageIndex() * params.getPageSize(), params.getPageSize() );

如果在编译时知道子句的数量,甚至不需要第二个lambda:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 MySearchParameters searchParameters = ...;
 SearchSession session = Search.session( entityManager );
 List<Book> hits = searchSession.search( Book.class )
         .where( f -> f.bool( b -> {
             b.must( f.matchAll() );
             if ( searchParameters.getSearchTerms() != null ) {
                 b.must( f.simpleQueryString().fields( "title", "description" )
                         .matching( searchParameters.getSearchTerms() )
                         .defaultOperator( BooleanOperator.AND ) );
             }
             // ...
             // BEGIN NEW CODE
             SomeComplexParameter complexParam = searchParameters.getSomeComplexParameter();
             if ( complexParam != null ) {
                 b.must( f.bool()
                         .should( f.match().field( "someField1" )
                             .matching( complexParam.getSomeField1() ) )
                         .should( f.match().field( "someField2" )
                             .matching( complexParam.getSomeField2() ) ) );
             }
             // END NEW CODE
         } ) )
         .fetchHits( params.getPageIndex() * params.getPageSize(), params.getPageSize() );

如果您真的不想在顶层使用lambda(为什么?),至少可以将lambda用于嵌套谓词:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
MySearchParameters searchParameters = ...;
SearchSession session = Search.session( entityManager );
SearchPredicateFactory pf = session.scope( Book.class ).predicate();
List<SearchPredicate> predicates = new ArrayList<>();

if ( searchParameters.getSearchTerms() != null ) {
    predicates.add( pf.simpleQueryString().fields( "title", "description" )
            .matching( searchParameters.getSearchTerms() )
            .defaultOperator( BooleanOperator.AND )
            .toPredicate() );
}

// ...

// BEGIN NEW CODE
SomeComplexParameter complexParam = searchParameters.getSomeComplexParameter();
if ( complexParam != null ) {
    predicates.add( pf.bool( b -> {
        b.should( pf.match().field( "someField1" )
            .matching( complexParam.getSomeField1() ) );
        b.should( pf.match().field( "someField2" )
            .matching( complexParam.getSomeField2() ) );
    } )
            .toPredicate() );
}
// END NEW CODE

List<Book> hits = searchSession.search( Book.class )
        .where( f -> f.bool( b -> {
            b.must( f.matchAll() );
            for ( SearchPredicate predicate : predicates ) {
                b.must( predicate );
            }
        } )

在这里,只要事先知道谓词的数量,就不需要lambda:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
MySearchParameters searchParameters = ...;
SearchSession session = Search.session( entityManager );
SearchPredicateFactory pf = session.scope( Book.class ).predicate();
List<SearchPredicate> predicates = new ArrayList<>();

if ( searchParameters.getSearchTerms() != null ) {
    predicates.add( pf.simpleQueryString().fields( "title", "description" )
            .matching( searchParameters.getSearchTerms() )
            .defaultOperator( BooleanOperator.AND )
            .toPredicate() );
}

// ...

// BEGIN NEW CODE
SomeComplexParameter complexParam = searchParameters.getSomeComplexParameter();
if ( complexParam != null ) {
    predicates.add( pf.bool()
            .should( pf.match().field( "someField1" )
                .matching( complexParam.getSomeField1() ) )
            .should( pf.match().field( "someField2" )
                 .matching( complexParam.getSomeField2() ) )
            .toPredicate() );
}
// END NEW CODE

List<Book> hits = searchSession.search( Book.class )
        .where( f -> f.bool( b -> {
            b.must( f.matchAll() );
            for ( SearchPredicate predicate : predicates ) {
                b.must( predicate );
            }
        } )
        .fetchHits( params.getPageIndex() * params.getPageSize(), params.getPageSize() );

最后,如果您真的想完全远离lambdas (但同样,为什么?),您可能可以这样做。但是,请注意,BooleanPredicateClausesStep的泛型类型参数在Hibernate搜索的次要版本中可能会发生变化,因此在升级时,这段代码更有可能中断。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
MySearchParameters searchParameters = ...;
SearchSession session = Search.session( entityManager );
SearchPredicateFactory pf = session.scope( Book.class ).predicate();
BooleanPredicateClausesStep<?> boolStep = pf.bool();

boolStep.must( f.matchAll() );

if ( searchParameters.getSearchTerms() != null ) {
    boolStep.must( pf.simpleQueryString().fields( "title", "description" )
            .matching( searchParameters.getSearchTerms() )
            .defaultOperator( BooleanOperator.AND ) );
}

// ...

SomeComplexParameter complexParam = searchParameters.getSomeComplexParameter();
if ( complexParam != null ) {
    BooleanPredicateClausesStep<?> boolStep2 = pf.bool();
    boolStep2.should( f.match().field( "someField1" )
            .matching( complexParam.getSomeField1() ) );
    boolStep2.should( f.match().field( "someField2" )
            .matching( complexParam.getSomeField2() ) );
    boolStep.must( boolStep2 );
}

SearchPredicate boolPredicate = boolStep.toPredicate();

List<Book> hits = searchSession.search( Book.class )
        .where( boolPredicate )
        .fetchHits( params.getPageIndex() * params.getPageSize(), params.getPageSize() );

如果使用JDK 11进行编译,更健壮的解决方案是使用var关键字:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
MySearchParameters searchParameters = ...;
SearchSession session = Search.session( entityManager );
SearchPredicateFactory pf = session.scope( Book.class ).predicate();
var boolStep = pf.bool();

boolStep.must( f.matchAll() );

if ( searchParameters.getSearchTerms() != null ) {
    boolStep.must( pf.simpleQueryString().fields( "title", "description" )
            .matching( searchParameters.getSearchTerms() )
            .defaultOperator( BooleanOperator.AND ) );
}

// ...

SomeComplexParameter complexParam = searchParameters.getSomeComplexParameter();
if ( complexParam != null ) {
    var boolStep2 = pf.bool();
    boolStep2.should( f.match().field( "someField1" )
            .matching( complexParam.getSomeField1() ) );
    boolStep2.should( f.match().field( "someField2" )
            .matching( complexParam.getSomeField2() ) );
    boolStep.must( boolStep2 );
}

SearchPredicate boolPredicate = boolStep.toPredicate();

List<Book> hits = searchSession.search( Book.class )
        .where( boolPredicate )
        .fetchHits( params.getPageIndex() * params.getPageSize(), params.getPageSize() );
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71470810

复制
相关文章
在 Hibernate Search 5.5 中对搜索结果进行排序
“秩序,秩序”- 有时不仅仅下议院尊敬的议员需要被喊着让排序,而且在特殊情况下 Hibernate 的查询结果也需要排序。
知忆
2021/06/08
2.9K0
Hibernate Annotation (Hibernate 注解)
英文:http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/
Hongten
2018/09/18
1.4K0
Hibernate 5 发行组件下载
Hibernate 项目小组提供了一系列发布组合(bundles),这些发布组合发布在 SourceForge 文件发布系统中。这些发布的包有 TGZ 和ZIP 格式。
HoneyMoose
2019/09/16
4170
Hibernate 5 发行组件下载
Hibernate 项目小组提供了一系列发布组合(bundles),这些发布组合发布在 SourceForge 文件发布系统中。这些发布的包有 TGZ 和ZIP 格式。
HoneyMoose
2019/09/16
4710
hibernate的hql查询语句总结 转
在这里通过定义了三个类,Special、Classroom、Student来做测试,Special与Classroom是一对多,Classroom与Student是一对多的关系,这里仅仅贴出这三个bean的属性代码:
stys35
2019/03/05
7920
加速你的Hibernate引擎(上) 转
Hibernate是最流行的对象关系映射(ORM)引擎之一,它提供了数据持久化和查询服务。
九州暮云
2019/08/21
6230
加速你的Hibernate引擎(上)
                                                                                                    转
【转】Spring Boot 2.0.2 使用 hibernate validator
把一个旧项目的mybatis-plus从2.x升级到3.x,发现hibernate validator提示【已过时】了,平时还没注意这个,强迫症还是把它处理了,小记一下: 把下面的
IT晴天
2019/04/01
1K0
Spring+SpringMVC+Hibernate简单整合(转)
SpringMVC又一个漂亮的web框架,他与Struts2并驾齐驱,Struts出世早而占据了一定优势,下面同样做一个简单的应用实例,介绍SpringMVC的基本用法,接下来的博客也将梳理一下Struts2和SpringMVC的一些异同,通过梳理和旧知识的联系,让学习的成本变低,花很短的时间就可以了解一门貌似新的技术,其实本质没变。
yaohong
2019/09/11
8560
Hibernate
一、什么是 Hibernate? Hibernate 是一个基于元数据的轻量级的 ORM 框架: 1、元数据(Meta Data):data about data(数据的数据),也就是说描述一个对
用户2038009
2021/03/08
1.3K0
【Hibernate】Hibernate框架配置详解
通过Hibernate我们可以方便地操作数据库读取出来的信息,减少了繁琐的JDBC操作。
陈树义
2022/04/29
1.4K0
Hibernate的入门(Hibernate的环境搭建、Hibernate的API)
Hibernate第一天(Hibernate的环境搭建、Hibernate的API、Hibernate的CRUD)
AlbertYang
2020/09/08
1.2K0
Hibernate的入门(Hibernate的环境搭建、Hibernate的API)
Hibernate配置access Hibernate 连接 access
个人测试结果,还是使用方法一比较妥当。方法3出现了一个奇怪错误~~ 1、Hibernate对于Access的支持 方法一: 下载两个jar包,一个是Access的JDBC驱动包;另一个是数据库方言包,里面有支持Access方言的类。 下载地址:http://www.hxtt.com/access.zip,http://www.hxtt.com/test/hibernate.zip。 配置如下:(URL那里可以使用相对路径) xml 代码 <property name="hibernate.dialec
用户1258909
2018/07/03
2.3K0
搜索(6)
 题目大意是在一个nxn的方阵地图上,每一个方格都标记+号或者-号,要从A点到B点。题目要求移动路线要+-交替,问怎么移动从A到B才是最短路径?  同样的,这道题也是一道2D网格图上的最短路径问题。我们仍然采用相同的思路来解决它  相较于上一讲的问题,本题主要有以下两个个不同之处:
mathor
2018/07/24
6500
搜索(6)
Hibernate 的应用(Hibernate 的结构)?
SessionFactory sessionFactory = new Configuration().configure().
MickyInvQ
2020/09/27
7490
【Hibernate那点事儿】—— Hibernate知识总结
前言: 上一篇简单的讲解了下Hibernate的基础知识。这里对Hibernate比较重要的一些知识点,进行总结和归纳。 总结的知识点: 1 关于hibernate映射的实体类标识符访问权
用户1154259
2018/01/18
1.1K0
【Hibernate那点事儿】—— Hibernate知识总结
Hibernate 配置hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hi
Twcat_tree
2022/11/30
7820
Hibernate 5 升级后 getProperties 错误
Google 搜索也找不到什么好的回答。经过我们对源代码的分析和排查,我们发现这是一个 JPA 版本不兼容的问题。
HoneyMoose
2019/10/18
6320
Hibernate 5 升级后 getProperties 错误
Hibernate 5 Maven 仓库的 Artifacts
Hibernate artifacts 官方发布的仓库在 JBoss Maven repository 中。Hibernate 发布的 artifacts 也会同时同步到 Maven Central 仓库中,这是一个自动同步进程(可能会有一些延迟)。
HoneyMoose
2019/09/16
4180
Hibernate 5 Maven 仓库的 Artifacts
Hibernate artifacts 官方发布的仓库在 JBoss Maven repository 中。Hibernate 发布的 artifacts 也会同时同步到 Maven Central 仓库中,这是一个自动同步进程(可能会有一些延迟)。
HoneyMoose
2019/09/16
4690
Hibernate 5 的模块/包(modules/artifacts)
Hibernate 的功能被拆分成一系列的模块/包(modules/artifacts),其目的是为了对依赖进行独立(模块化)。
HoneyMoose
2019/09/16
4740

相似问题

例外:在Hibernate搜索5和Hibernate搜索6之间更改配置属性

15

Hibernate搜索6更像这样

12

Hibernate搜索6:方法映射

11

连接表中的Hibernate谓词搜索

115

Hibernate搜索6 @ProjectionConstructor不工作

27
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文