解決 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);
}

上述代碼嘗試構建一個查詢,要求 broadcastTimeplanBroadcastTime 在指定的 startTimeendTime 范圍內。但錯誤的使用方式導致了無效的 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()));}
}
修復后的查詢

對于 startTimeendTime 都提供的情況,生成的 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 組合 broadcastTimeplanBroadcastTime 的條件,保持了預期的 OR 邏輯,避免生成無效結構。

  3. 避免沖突
    修復后的查詢結構消除了格式錯誤,Spring Data MongoDB 能夠正確處理所有條件,不會觸發 “second ‘null’ criteria” 錯誤。


注意事項
  • 測試驗證
    應用修復后,建議使用不同的輸入組合(例如,提供 startTimeendTime、僅提供 startTime、不同 fallback 值)測試查詢,確保結果符合預期。

  • 空值處理
    確保 StringUtil.isNotEmptyStringnull 和空字符串的處理符合預期,以避免意外添加條件。


總結

InvalidMongoDbApiUsageException 錯誤源于在同一字段的范圍查詢中誤用 .andOperator,導致無效的 MongoDB 查詢結構。通過在每個字段的 Criteria 上直接鏈式調用 .lte().gte(),并使用 .orOperator 組合不同字段的條件,可以構建正確的查詢。使用上述修復后的代碼即可解決問題。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/902478.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/902478.shtml
英文地址,請注明出處:http://en.pswp.cn/news/902478.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋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;掌握其使用過程中的注意事項和最佳實踐至關…