解决 MongoDB 查询中的 `InvalidMongoDbApiUsageException` 错误

您在使用 Spring Data MongoDB 时遇到了 InvalidMongoDbApiUsageException 异常,错误信息如下:

“由于 com.mongodb.BasicDocument 的限制,您无法添加第二个 ‘null’ 条件。查询已经包含 ‘{ “KaTeX parse error: Expected '}', got 'EOF' at end of input: …castTime" : { "lte” : { “KaTeX parse error: Expected 'EOF', got '}' at position 31: …4-21T16:00:00Z"}̲}, "and” : [{ “broadcastTime” : { “KaTeX parse error: Expected '}', got 'EOF' at end of input: gte" : { "date” : “2025-04-20T16:00:00Z”}}}]}, { “planBroadcastTime” : { “KaTeX parse error: Expected '}', got 'EOF' at end of input: lte" : { "date” : “2025-04-21T16:00:00Z”}}, “KaTeX parse error: Expected '}', got 'EOF' at end of input: …castTime" : { "gte” : { “$date” : “2025-04-20T16:00:00Z”}}}]}]}’”

这个错误是由使用 Criteria API 构建 MongoDB 查询时的错误用法引起的。以下是问题的分析和解决方案。


问题分析

假设您的代码类似于以下形式,用于根据时间范围和回退条件查询数据:

Query query = new Query();
if (liveRoomReq.getStartTime() != null && liveRoomReq.getEndTime() != null) {Criteria timeCriteria = new Criteria().orOperator(Criteria.where("broadcastTime").lte(liveRoomReq.getEndTime()).andOperator(Criteria.where("broadcastTime").gte(liveRoomReq.getStartTime())),Criteria.where("planBroadcastTime").lte(liveRoomReq.getEndTime()).andOperator(Criteria.where("planBroadcastTime").gte(liveRoomReq.getStartTime())));query.addCriteria(timeCriteria);
}

上述代码尝试构建一个查询,要求 broadcastTime 或 planBroadcastTime 在指定的 startTime 和 endTime 范围内。但错误的使用方式导致了无效的 MongoDB 查询结构。

生成的错误查询

根据错误信息,生成的 MongoDB 查询如下:

{"$or": [{"broadcastTime": { "$lte": { "$date": "2025-04-21T16:00:00Z" } },"$and": [ { "broadcastTime": { "$gte": { "$date": "2025-04-20T16:00:00Z" } } } ]},{"planBroadcastTime": { "$lte": { "$date": "2025-04-21T16:00:00Z" } },"$and": [ { "planBroadcastTime": { "$gte": { "$date": "2025-04-20T16:00:00Z" } } } ]}]
}

这种结构是无效的,因为 MongoDB 不允许在同一字段的条件中混合使用字段运算符(如 $lte)和逻辑运算符(如 $and)。正确的范围查询应该将 $lte 和 $gte 组合在同一个字段的对象中。

错误原因

问题出在 .andOperator 的误用上:

  • 在 Spring Data MongoDB 中,.andOperator 用于将多个不同字段的条件以 AND 逻辑组合。
  • 对于同一字段的范围查询(如 broadcastTime 需要同时满足 <= endTime 和 >= startTime),应该在单个 Criteria 上直接链式调用 .lte() 和 .gte()。

错误的用法生成了不符合 MongoDB 语法的查询结构,导致 Spring Data MongoDB 在处理后续条件时抛出异常。


解决方案

修复方法是调整 Criteria 的构建方式,在同一字段的条件上直接使用链式调用,而不是使用 .andOperator。以下是更正后的代码:

Query query = new Query();
if (liveRoomReq.getStartTime() != null && liveRoomReq.getEndTime() != null) {Criteria broadcastTimeCriteria = Criteria.where("broadcastTime").lte(liveRoomReq.getEndTime()).gte(liveRoomReq.getStartTime());Criteria planBroadcastTimeCriteria = Criteria.where("planBroadcastTime").lte(liveRoomReq.getEndTime()).gte(liveRoomReq.getStartTime());Criteria timeCriteria = new Criteria().orOperator(broadcastTimeCriteria, planBroadcastTimeCriteria);query.addCriteria(timeCriteria);
} else if (liveRoomReq.getStartTime() != null) {Criteria broadcastTimeCriteria = Criteria.where("broadcastTime").gte(liveRoomReq.getStartTime());Criteria planBroadcastTimeCriteria = Criteria.where("planBroadcastTime").gte(liveRoomReq.getStartTime());Criteria timeCriteria = new Criteria().orOperator(broadcastTimeCriteria, planBroadcastTimeCriteria);query.addCriteria(timeCriteria);
}
// 添加回退条件(示例)
if (StringUtil.isNotEmptyString(liveRoomReq.getFallback())) {if ("0".equals(liveRoomReq.getFallback())) {Criteria fallbackCriteria = new Criteria().orOperator(Criteria.where("fallback").in(liveRoomReq.getFallback()),Criteria.where("fallback").exists(false));query.addCriteria(fallbackCriteria);} else {query.addCriteria(Criteria.where("fallback").is(liveRoomReq.getFallback()));}
}
修复后的查询

对于 startTime 和 endTime 都提供的情况,生成的 MongoDB 查询如下:

{"$or": [{ "broadcastTime": { "$lte": "2025-04-21T16:00:00Z", "$gte": "2025-04-20T16:00:00Z" } },{ "planBroadcastTime": { "$lte": "2025-04-21T16:00:00Z", "$gte": "2025-04-20T16:00:00Z" } }]
}

如果还添加了 fallback 条件(例如 fallback = "0"),最终查询可能是:

{"$and": [{"$or": [{ "broadcastTime": { "$lte": "2025-04-21T16:00:00Z", "$gte": "2025-04-20T16:00:00Z" } },{ "planBroadcastTime": { "$lte": "2025-04-21T16:00:00Z", "$gte": "2025-04-20T16:00:00Z" } }]},{"$or": [{ "fallback": { "$in": ["0"] } },{ "fallback": { "$exists": false } }]}]
}

这是一个有效的 MongoDB 查询结构。


为什么这个方案有效
  1. 正确的范围查询
    在同一字段的 Criteria 上链式调用 .lte() 和 .gte(),确保条件被正确分组到一个对象中,符合 MongoDB 的语法要求。

  2. 逻辑运算符的正确使用
    使用 .orOperator 组合 broadcastTime 和 planBroadcastTime 的条件,保持了预期的 OR 逻辑,避免生成无效结构。

  3. 避免冲突
    修复后的查询结构消除了格式错误,Spring Data MongoDB 能够正确处理所有条件,不会触发 “second ‘null’ criteria” 错误。


注意事项
  • 测试验证
    应用修复后,建议使用不同的输入组合(例如,提供 startTime 和 endTime、仅提供 startTime、不同 fallback 值)测试查询,确保结果符合预期。

  • 空值处理
    确保 StringUtil.isNotEmptyString 对 null 和空字符串的处理符合预期,以避免意外添加条件。


总结

InvalidMongoDbApiUsageException 错误源于在同一字段的范围查询中误用 .andOperator,导致无效的 MongoDB 查询结构。通过在每个字段的 Criteria 上直接链式调用 .lte() 和 .gte(),并使用 .orOperator 组合不同字段的条件,可以构建正确的查询。使用上述修复后的代码即可解决问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.tpcf.cn/news/902478.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一个关于相对速度的假想的故事-4

回到公式&#xff0c; 正写速度叠加和倒写速度叠加的倒写相等&#xff0c;这就是这个表达式所要表达的意思。但倒写叠加用的是减法&#xff0c;而正写叠加用的是加法。当然是这样&#xff0c;因为正写叠加要的是单位时间上完成更远的距离&#xff0c;而倒写叠加说的是单位距离需…

重学React(一):描述UI

背景&#xff1a;React现在已经更新到19了&#xff0c;文档地址也做了全面的更新&#xff0c;上一次系统性的学习还是在16-17的大版本更新。所以&#xff0c;现在就开始重新学习吧&#xff5e; 学习内容&#xff1a; React官网教程&#xff1a;https://zh-hans.react.dev/lea…

AI大模型:(二)2.3 预训练自己的模型

目录 1.预训练原理 2.预训练范式 1.未标注数据 2.标注数据 3.有正确答案、也有错误答案 3.手撕transform模型 3.1.transform模型代码 3.2.训练数据集 3.3.预训练 3.4.推理 4.如何选择模型

gradle可用的下载地址(免费)

这几天接手一个老项目&#xff0c;想找gradle老版本的&#xff0c;但一搜&#xff0c;虽然在CSDN上搜索出来一堆&#xff0c;但都是收费&#xff0c;有些甚至要几十积分(吃相有点难看了)。 我找了一个能访问的地址&#xff0c;特地分享出来&#xff0c;有需要的自取&#xff01…

vue3新增特性

一、Vue 3 新增特性 1. Composition API 概述: Composition API 提供了一种更灵活和强大的方式来组织和复用逻辑。适用于复杂组件和逻辑复用场景。主要功能: setup 函数:组件的入口点,用于定义响应式数据、方法、生命周期钩子等。响应式 API:ref 和 reactive 提供更细粒度…

前端性能优化全攻略:JavaScript 优化、DOM 操作、内存管理、资源压缩与合并、构建工具及性能监控

1 为什么需要性能优化&#xff1f; 1.1 性能优化的核心价值&#xff1a;用户体验与业务指标 性能优化不仅是技术层面的追求&#xff0c;更是直接影响用户体验和业务成败的关键因素。 用户体验&#xff08;UX&#xff09;&#xff1a; 响应速度&#xff1a;用户期望页面加载时…

【Unity笔记】Unity + OpenXR项目无法启动SteamVR的排查与解决全指南

图片为AI生成 一、前言 随着Unity在XR领域全面转向OpenXR标准&#xff0c;越来越多的开发者选择使用OpenXR来构建跨平台的VR应用。但在项目实际部署中发现&#xff1a;打包成的EXE程序无法正常启动SteamVR&#xff0c;或者SteamVR未能识别到该应用。本文将以“Unity OpenXR …

Curl用法解析

Curl 用法解析 简介 Curl 是一个强大的命令行工具&#xff0c;主要用于从服务器发送 HTTP 请求并获取数据。它广泛应用于调试 RESTful API、文件上传下载、模拟用户交互等多种场景。下面是一些基本用法及常见参数的分析&#xff1a; 基础用法 curl [options] [URL]其中最基…

C语言教程(十一):C 语言中四种主要作用域及作用域嵌套遮蔽

一、引言 在 C 语言里&#xff0c;作用域指的是程序中变量、函数、类型等标识符能够被使用的范围。C 语言里有四种主要的作用域&#xff1a;块作用域、函数作用域、文件作用域和原型作用域&#xff0c;下面为你展开介绍&#xff1a; 二、块作用域 定义&#xff1a;块作用域是 C…

初次尝试Ghidra

最近看京东读书上有本书叫《Ghidra权威指南》&#xff0c;竟然是美国国家安全局出品的逆向工具&#xff0c;我真是孤陋寡闻&#xff0c;第一次听说。赶紧试试。 Release Ghidra 11.3.2 NationalSecurityAgency/ghidra GitHub 最新版本竟然是上周发布的&#xff0c;看来很活…

乐视系列玩机---乐视2 x620 x628等系列线刷救砖以及刷写第三方twrp 卡刷第三方固件步骤解析

乐视2 x620 x628 x626等,搭载了Helio X20处理器,mtk6797芯片。 通过博文了解💝💝💝 1💝💝💝-----详细解析乐视2 x620系列黑砖线刷救砖的步骤 2💝💝💝----官方两种更新卡刷步骤以及刷写第三方twrp过程与资源 3💝💝💝----乐视2 mtk系列机型救砖 刷…

web原生API AbortController网络请求取消方法使用介绍:防止按钮重复点击提交得最佳方案

在前端开发中&#xff0c;取消网络请求是一个常见的需求&#xff0c;尤其是在用户频繁操作或需要中断长时间请求的场景下。 AbortController 主要用于 ​优雅地管理和取消异步操作&#xff1a; 浏览器原生 API 一、代码解析 1. ​创建 AbortController 实例 const controlle…

2025智能驾驶趋势评估

以下是对2025年智能驾驶趋势的评估&#xff1a; 技术发展 • 自动驾驶级别提升&#xff1a;2025年有望成为L3级自动驾驶的商用元年。L3级自动驾驶技术开始从高端车型向20万元以下价格带下沉&#xff0c;部分车企如江淮和华为合作的尊界S800、小鹏汽车等都在积极推进L3级自动驾驶…

Spring MVC DispatcherServlet 的作用是什么? 它在整个请求处理流程中扮演了什么角色?为什么它是核心?

DispatcherServlet 是 Spring MVC 框架的绝对核心和灵魂。它扮演着前端控制器&#xff08;Front Controller&#xff09;的角色&#xff0c;是所有进入 Spring MVC 应用程序的 HTTP 请求的统一入口点和中央调度枢纽。 一、 DispatcherServlet 的核心作用和职责&#xff1a; 请…

Linux 内核中 cgroup 子系统 cpuset 是什么?

cpuset 是 Linux 内核中 cgroup&#xff08;控制组&#xff09; 的一个子系统&#xff0c;用于将一组进程&#xff08;或任务&#xff09;绑定到特定的 CPU 核心和 内存节点&#xff08;NUMA 节点&#xff09;上运行。它通过限制进程的 CPU 和内存资源的使用范围&#xff0c;优…

【MATLAB第115期】基于MATLAB的多元时间序列的ARIMAX的预测模型

【MATLAB第115期】基于MATLAB的多元时间序列的ARIMAX的预测模型 ‌一、简介 ARIMAX‌&#xff08;Autoregressive Integrated Moving Average with eXogenous inputs&#xff09;模型是一种结合自回归&#xff08;AR&#xff09;、差分&#xff08;I&#xff09;、移动平均&a…

数据库对象与权限管理-视图与索引管理

一、视图&#xff08;View&#xff09;管理 1. 视图的定义与本质 视图&#xff08;View&#xff09;是Oracle数据库中的逻辑表&#xff0c;它不直接存储数据&#xff0c;而是通过预定义的SQL查询动态生成结果集。视图的本质可以理解为&#xff1a; 虚拟表&#xff1a;用户可…

IPoIB驱动接收路径深度解析:从数据包到协议栈

引言 在InfiniBand网络中,IPoIB(IP-over-InfiniBand)协议通过封装和模拟以太网行为,使得传统IP应用能够无缝运行。其接收路径是性能优化的关键环节,涉及硬件中断处理、内存管理、协议解析等多个复杂步骤。本文以Linux内核中ipoib_ib_handle_rx_wc_rss函数为核心,结合IPo…

Oracle高级语法篇-分析函数详解

Oracle 分析函数详解 在Oracle数据库中&#xff0c;分析函数&#xff08;Analytical Functions&#xff09;是一类非常强大的工具&#xff0c;它们允许在查询结果集上进行复杂的计算和分析&#xff0c;而无需使用自连接或子查询等复杂操作。本文将详细介绍Oracle分析函数的使用…

使用 Nacos 的注意事项与最佳实践

&#x1f4f9; 背景 Nacos 凭借其强大&#x1f4aa;的服务发现、配置管理和服务管理能力&#xff0c;成为构建分布式系统的得力助手。然而&#xff0c;要充分发挥 Nacos 的优势&#xff0c;实现系统的高性能、高可用&#xff0c;掌握其使用过程中的注意事项和最佳实践至关…