You need to enable JavaScript to run this app. Mongoose查询ingredients全部元素属于inventory的文档返回零结果
优惠活动
大模型
产品
解决方案
定价
更多

Mongoose查询ingredients全部元素属于inventory的文档返回零结果

问题原因

你当前使用$all的逻辑完全和需求相反:
ingredients: { $all: inventory }的语义是要求ingredients数组包含inventory数组的所有元素,而你的需求是ingredients数组的每一个元素都至少能匹配到inventory中的一个关键词,自然返回空结果。

解决方案

方案1:基于现有结构直接查询(无需改数据)

你可以使用聚合查询实现需求,逻辑是统计每个文档的ingredients中无法匹配inventory关键词的元素数量,筛选数量为0的文档即可:
首先保留你将inventory转为不区分大小写正则的逻辑:

let inventory = ["lemons", "butter", "egg", "milk", "bread", "salmon", "asparagus", "pepper"];
const inventoryRegex = inventory.map(i => new RegExp(i, "i"));

之后执行聚合查询:

Recipe.aggregate([
  {
    $addFields: {
      // 统计未匹配任何关键词的食材数量
      unMatchedCount: {
        $size: {
          $filter: {
            input: "$ingredients",
            cond: {
              $not: {
                $or: inventoryRegex.map(regex => ({
                  $regexMatch: { input: "$$this", regex: regex }
                }))
              }
            }
          }
        }
      }
    }
  },
  // 未匹配数量为0即符合要求
  { $match: { unMatchedCount: 0 } },
  // 可选:删除临时统计字段
  { $unset: "unMatchedCount" }
])

该方案在数千条数据的场景下性能完全可用。

方案2:优化结构提升查询性能

如果后续数据量增长,可以提前将每个ingredients中的食材关键词提取为单独的数组字段,比如新增ingredientKeys字段,示例结构如下:

{
  recipe: "recipe2",
  ingredients: [ "2 lemons", "2 tbsp butter", "1 large egg" ],
  ingredientKeys: [ "lemons", "butter", "egg" ]
}

优化后查询可以完全避免正则匹配,性能提升明显:

Recipe.find({
  ingredientKeys: { $not: { $elemMatch: { $nin: inventory } } }
})

该查询的逻辑是:不存在任何一个ingredientKeys元素不在inventory数组中,即所有食材关键词都在你的库存范围内。

内容的提问来源于stack exchange,提问作者Jarki

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 07:45:08