Mongoose $all查询不符合预期但MongoDB Compass可正常运行的求助
MongoDB Mongoose 中嵌套数组 $all 查询异常问题
Schema 定义片段
{ info: { // item_info 可为 undefined item_info: { enchants: [{name: String, level: Number}] } } }
info 和 item_info 均为独立 Schema,且 _id 设为 false。
问题描述
使用以下查询语句时:
{"info.item_info.enchants": {$all: [{name: "growth", level: 5}, {name: "protection", level: 5}]}}
- 在 MongoDB Compass 中可正常运行,返回所有
enchants数组同时包含{name: "growth", level: 5}和{name: "protection", level: 5}的文档; - 在 Mongoose 的
<ModelName>.find()中执行时,却返回所有没有item_info字段的文档。
替换查询操作符后表现正常:
- 将
$all替换为$in,可正常返回包含任一指定元素的文档; - 直接传入数组(无操作符),可正常返回恰好包含这两个元素的文档。
历史正常结构
此前 enchants 字段为以下结构时,$all 查询可正常工作:
// 省略其他字段 enchants: [ {"protection": 5}, {"growth": 5} ]
改为包含 name 和 level 字段的结构后,$all 查询出现异常。
修复方案与变通方法
方法1:使用 $and + $elemMatch 替代 $all
通过明确的多条件匹配,绕过 Mongoose 对 $all 的解析问题:
ModelName.find({ $and: [ {"info.item_info.enchants": {$elemMatch: {name: "growth", level: 5}}}, {"info.item_info.enchants": {$elemMatch: {name: "protection", level: 5}}} ] })
方法2:使用 MongoDB 原生集合查询
绕过 Mongoose 的 Schema 解析逻辑,直接调用原生集合的查询方法:
ModelName.collection.find({ "info.item_info.enchants": { $all: [ {name: "growth", level: 5}, {name: "protection", level: 5} ] } }).toArray()
原因分析
该问题大概率是 Mongoose 在处理嵌套 Schema 下的对象数组 $all 查询时,解析逻辑出现偏差——将缺失 item_info 字段(即 enchants 数组不存在)的文档错误判定为匹配条件,而 MongoDB 原生查询(如 Compass)的逻辑是正确的。
内容的提问来源于stack exchange,提问作者Xerxis
相关产品推荐
相关产品推荐

