莱芜可信赖的网站建设,台州国强建设网站,雅虎搜索,昆明做网站费用您在使用 Spring Data MongoDB 时遇到了 InvalidMongoDbApiUsageException 异常#xff0c;错误信息如下#xff1a; “由于 com.mongodb.BasicDocument 的限制#xff0c;您无法添加第二个 ‘null’ 条件。查询已经包含 ‘{ “KaTeX parse error: Expected }, got EOF at e…您在使用 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 查询结构。 为什么这个方案有效 正确的范围查询 在同一字段的 Criteria 上链式调用 .lte() 和 .gte()确保条件被正确分组到一个对象中符合 MongoDB 的语法要求。 逻辑运算符的正确使用 使用 .orOperator 组合 broadcastTime 和 planBroadcastTime 的条件保持了预期的 OR 逻辑避免生成无效结构。 避免冲突 修复后的查询结构消除了格式错误Spring Data MongoDB 能够正确处理所有条件不会触发 “second ‘null’ criteria” 错误。 注意事项 测试验证 应用修复后建议使用不同的输入组合例如提供 startTime 和 endTime、仅提供 startTime、不同 fallback 值测试查询确保结果符合预期。 空值处理 确保 StringUtil.isNotEmptyString 对 null 和空字符串的处理符合预期以避免意外添加条件。 总结
InvalidMongoDbApiUsageException 错误源于在同一字段的范围查询中误用 .andOperator导致无效的 MongoDB 查询结构。通过在每个字段的 Criteria 上直接链式调用 .lte() 和 .gte()并使用 .orOperator 组合不同字段的条件可以构建正确的查询。使用上述修复后的代码即可解决问题。