首页 > 解决方案 > MongoDB:数组大小与 $where - ReferenceError

问题描述

对于 MongoDB 4.4.6

对于带有数组的集合 - 如果我使用

db.fighters.find({"close_attacks": {$size: 3}},
                 {"_id": 0, "biography": 0})
           .pretty()
db.fighters.find({"close_attacks.2" : { $exists: true }},
                 {"_id": 0, "biography": 0})
           .pretty()
db.fighters.find({"close_attacks.3" : { $exists: true }},
                 {"_id": 0, "biography": 0})
           .pretty()

一切安好工作

我想使用>=#(即>=3),我做了一项研究,在 SO 的许多帖子中出现了两个选项,一个已经在上面显示:使用数组的索引和 #exists,另一个正在使用$where

所以在 Compass 通过 _ mongosh beta我试过:

db.fighters.find({$where: "this.close_attacks.length >= 3"},
                 {"_id": 0, "biography": 0})
           .pretty()

并出现

MongoError: TypeError: this.close_attacks is undefined :
@:1:15

如果我删除this

db.fighters.find({$where: "close_attacks.length >= 3"},
                 {"_id": 0, "biography": 0})
           .pretty()

它出现

MongoError: ReferenceError: close_attacks is not defined :
@:1:15

有什么遗漏或错误?

标签: mongodbmongodb-query

解决方案


您可以使用$expr运算符来使用聚合运算符$gte$size,

首选聚合替代方案
从 MongoDB 3.6 开始,$expr运算符允许在查询语言中使用聚合表达式。

db.fighters.find({
  $expr: {
    $gte: [{ $size: "$close_attacks" }, 3]
  }
},
{"_id": 0, "biography": 0}).pretty()

MongoError:$size 的参数必须是一个数组,但类型为:缺失

您可以通过使用检查其类型来避免此类错误$type

db.fighters.find({
  $and: [
    { close_attacks: { $type: "array" } },
    {
      $expr: {
        $gte: [{ $size: "$close_attacks" }, 3]
      }
    }
  ]
},
{"_id": 0, "biography": 0}).pretty()

注意:
从 MongoDB 4.4 开始,$where不再支持已弃用的具有范围的 BSON 类型 JavaScript 代码(BSON 类型 15)。该$where算子仅支持 BSON 类型 String(BSON 类型 2)或 BSON 类型 JavaScript(BSON 类型 13)。$where自 MongoDB 4.2.1 以来,已弃用BSON 类型 JavaScript 和范围 for 。

这两个块在$where中可用


推荐阅读