You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 13:06:26