MongoDB - $size的参数必须是一个数组,但类型为EOO/缺失。

78

尝试使用icCube创建一个MongoDB数据源。想法是将数组的大小作为新字段返回。类似于:

$project:
{ 
 "people": 1, 
 "Count myFieldArray" : {$size : "$myFieldArray" }
}

但是我在获取某些记录时出现了以下错误:

The argument to $size must be an Array, but was of type: EOO

如果字段为空或不是数组,有没有办法使大小为0(消除错误)?

3个回答

156
您可以在这里使用$ifNull运算符。根据给定的错误信息,该字段似乎要么不是数组,要么不存在:
{ "$project": {
    "people": 1,
    "Count": { 
        "$size": { "$ifNull": [ "$myFieldArray", [] ] }
    }
}}

此外,您可能需要在$match中检查$type,以防这些存在但不是数组。


2
非常感谢,它可以工作了。奇怪的是未定义字段的$size不为0(实际上对于所有非数组类型都为0)。我希望一个非关系型数据库会更宽容(以防MongoDB的人看到这个 :-) )。 - ic3
2
@ic3并不完全正确,这也是为什么$ifNull存在的原因。同样的注意事项也适用于像$unwind这样的运算符,在使用时需要小心确保数组不为空或缺失,否则可能会导致删除父文档或产生类似的错误。 - Neil Lunn

10

从MongoDB 3.2及更高版本开始,您可以使用 $isArray 来检查您的字段是否为数组,结合 $cond 运算符来在评估时返回该字段,当它与 $isArray 相匹配时:

{ "$project": {
    "people": 1,
    "myFieldArrayCount": { 
        "$size": { 
            "$cond": [ 
                { "$isArray": "$myFieldArray" }, 
                "$myFieldArray", 
                []
            ]
        } 
    }
}}

1
它可以工作,但比$ifNull慢。 - EvgenyKolyakov

0
另一个解决方法是使用去除空值的文档。
$match: {myFieldArray: { $elemMatch: { $exists: true } }}

此外,作为 $size 的参数的文档字段(在这里是 "$myFieldArray")必须同时包含在投影中。
$project:
{ 
 "people": 1,
 "myFieldArray":1,
 "Count myFieldArray" : {$size : "$myFieldArray" }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接