2
db.getCollection('docs').aggregate([
    {
      $project: {
        "has books" : 
          { $in: ["A", {$cond: {if: {$gt: ["$books", null]}, then: "$books", else: []}}] }
      }
    }
])

上述查询在独立 MongoDB 上执行时有效,并给出以下结果:

/* 1 */
{
    "_id" : ObjectId("5ca6023ccb9228c0ab417ad5"),
    "has books" : false
}

/* 2 */
{
    "_id" : ObjectId("5ca631b8cb9228c0ab419174"),
    "has books" : false
}

/* 3 */
{
    "_id" : ObjectId("5ca64006cb9228c0ab419a54"),
    "has books" : false
}

/* 4 */
{
    "_id" : ObjectId("5ca6e093cb9228c0ab41cf7c"),
    "has books" : true
}

/* 5 */
{
    "_id" : ObjectId("5ca6eee9cb9228c0ab41d594"),
    "has books" : false
}

但是,在 AWS DocumentDB 实例上执行相同的查询时,会出现以下错误:

Failed to execute script.

Error: command failed: {
    "ok" : 0,
    "errmsg" : "$in requires an array as a second argument, found: object",
    "code" : 40081
} : aggregate failed 
Details:
_getErrorWithCode@src/mongo/shell/utils.js:25:13
doassert@src/mongo/shell/assert.js:18:14
_assertCommandWorked@src/mongo/shell/assert.js:534:17
assert.commandWorked@src/mongo/shell/assert.js:618:16
DB.prototype._runAggregate@src/mongo/shell/db.js:260:9
DBCollection.prototype.aggregate@src/mongo/shell/collection.js:1062:12
DBCollection.prototype.aggregate@:1:355
@(shell):1:1

查询的目的是检查数组中是否存在特定值,输出预期为布尔值。该docs集合有一个数组 field =books可以为 null,因此为了克服 null 问题,如果字段不存在或为 null ,$cond则使用空数组替换字段。AWS DocumentDB 不支持,因此无法使用。books$ifNull

更正上述查询或使用 AWS DocumentDB 支持的替代查询以获得预期结果的建议将大有帮助。

4

1 回答 1

1

所以问题是你的books字段既不null是数组也不是数组。

您可以像这样使用$ifNull来解决这个问题:


db.getCollection('docs').aggregate([
    {
        $project: {
            "has books" :
                { $in: ["A", {$cond: {if: {$ne: [{$ifNull: ["$books", null]}, null]}, then: "$books", else: []}}] }
        }
    }
])

或使用$isArray

db.getCollection('docs').aggregate([
    {
        $project: {
            "has books" :
                { $in: ["A", {$cond: {if: {$isArray: "$books"}, then: "$books", else: []}}] }
        }
    }
])

或者不使用这些运算符中的任何一个,因为它们不受支持,那么您可以添加一个type字段然后继续:

db.getCollection('docs').aggregate([
    {
        $addFields: {
            booksType: {$type: "$books"}
        }
    },
    {
        $project: {
            "has books" :
                { $in: ["A", {$cond: {if: {$eq: ["$booksType", 4]}, then: "$books", else: []}}] }
        }
    }
])
于 2020-06-11T13:22:02.303 回答