MongoDb - 在 $addFields 期间检查数组中是否存在参数

MongoDb - checking existence of param in array during $addFields

给出这个幻想数据集(提前抱歉,但我无法正确格式化):

我需要创建一个 MongoDb 管道来创建一个新字段,并且这个新字段应该能够在缺少“k”参数或空。

这是我的尝试:

...    
{
    "$addFields": {
        "colors_field": {
            "r": "$colors.r",
            "g": "$colors.g",
            "b": "$colors.b",
            "k": {
                "$cond": {
                    "if": {
                       "$or": [
                            {"$eq": [ "$colors.k", "" ]},
                            {"$eq": [ "$colors.k", null ]},
                            {"$colors.k": { "$exists": false}}
                            ]
                    },
                    "then": "",
                    "else": "$colors.k"
                }
            }
        }
    }
}

我尝试使用 $exists 但我无法让它工作,因为我调用要检查的值的方式:要么我输入“$colors.k”,它 return 是一个“ MongoError: Unrecognized expression” 或者我不这样做,它会 return a “MongoError: FieldPath field names may not contain '.'”。 我还尝试检查该字段的长度,但如果缺少该字段,它将崩溃。

您的查询存在问题,因为您使用的是查询运算符 $exists 在管道内(只有 $match 阶段允许这样做)。

我们在聚合中没有“$exists”运算符,但我们可以使用 $type 和“missing”来实现,但这里你想要存在或 null,所以 $ifnull 是正确的方法这样做(确实如此,名称是误导,如果不存在或为空)。

查询(3 种方法)

  1. $type 和“缺失”(如果你想要的话,正确的方法是存在),这里你想要空值,所以它变得更大查询
  2. $ifnull这是最短的路
  3. $cond not-exists 或 null 都是假值,所以这也有效,但是 小心这一点,因为如果颜色是假的,它也会使它成为 ""

*在您的情况下,简短而安全的解决方案是 2

Test code here

db.collection.aggregate([
  {
    "$set": {
      "k-cond": {
        "$cond": [
          {
            "$or": [
              {
                "$eq": [
                  "$colors.k",
                  null
                ]
              },
              {
                "$eq": [
                  {
                    "$type": "$colors.k"
                  },
                  "missing"
                ]
              }
            ]
          },
          "",
          "$colors.k"
        ]
      },
      "k-ifnull": {
        "$ifNull": [
          "$colors.k",
          ""
        ]
      },
      "k-if": {
        "$cond": [
          "$colors.k",
          "$colors.k",
          ""
        ]
      }
    }
  }
])