【发布时间】:2022-01-14 15:39:12
【问题描述】:
我有一个看起来像这样的文档:
{
"_id": ObjectId(),
"employees": [
{
"_id": ObjectId(),
"sharedBranches": [
ObjectId(),
ObjectId()
]
},
{
"_id": ObjectId()
}
]
}
我正在尝试在 sharedBranches 字段中返回包含我的输入 ObjectId 的文档,并向下过滤 employees 数组,使其仅包含 sharedBranches 包含我的输入 ObjectId 的对象。
然而,并不是每个employee 对象(即employees 数组中的元素)都包含sharedBranches 字段。我的查询返回一个错误,我很确定这是由于 Nulls,但我无法弄清楚 $isNull 的语法。这是我的查询。 (注意 branch_id 是我正在搜索的输入 ObjectId。
collection = client["collection"]["documents"]
pipeline = [
{
"$match": {
"employees.sharedBranches": {"$elemMatch": {"$eq": ObjectId(branch_id)}},
}
},
{
"$project": {
"employees": {
"$filter": {
"input": "$employees",
"as": "employees",
"cond": {"$in": [ObjectId(branch_id), {"$ifNull": ["$$employees.sharedBranches", []]}]}
}
}
}
}
]
此查询返回错误:
OperationFailure: $in requires an array as a second argument, found: object, full error: {'ok': 0.0, 'code': 40081, 'errmsg': '$in requires an array as a second argument, found: object', 'operationTime': Timestamp(1639079887, 1)}
似乎$ifNull 的东西没有对数组进行评估。如果我删除 $ifNull 的东西,并尝试直接在数组上使用 $in (所以我的 $cond 看起来像:
"cond": {"$in": [ObjectId(branch_id), "$$employees.sharedBranches"]},
我收到此错误:
OperationFailure: $in requires an array as a second argument, found: string, full error: {'ok': 0.0, 'code': 40081, 'errmsg': '$in requires an array as a second argument, found: string', 'operationTime': Timestamp(1639080588, 1)}
所以我不知道如何解决这个问题。 $ifNull 是我的问题吗?我误认为它根本就需要它吗?
【问题讨论】:
-
found: object- 我很确定 null 不是一个对象。你试过用$type检查数组吗? -
很奇怪。我欺骗了您的输入数据并创建了相同的管道并且它有效。
$ifNullexpr 正确地将空白(缺失)数组转换为[]并且$filter工作正常。 -
我认为发生了这样的事情:构建
sharedBranches数组的东西创建了一个字符串 val 而不是一个数组。