【问题标题】:add key to nested array with condition使用条件将键添加到嵌套数组
【发布时间】:2018-11-21 00:15:20
【问题描述】:

我在 mongodb 中有一个简单的数据结构:

{
  _id: ObjectID,
 name: 'Name',
 birthday: '25.05.2001'
 items: [
          {
             _id: ObjectID,
             name: 'ItemName',
             info: 'ItemInfo',
           },
           {
             _id: ObjectID,
             name: 'ItemName',
             info: 'ItemInfo',
           }
        ]
}

现在我想要一个查询,它将一个项目的 ObjectID (_id) 作为条件,并将包含数组中所有项目的对象返回给我,并将一个“选定”的新字段投影到一个字段中,值为 true 或 false每个数组项的结果:

我用这个查询尝试过:

 { $unwind: '$items' },
 {
    $project: {
       selected: {
          $cond: { if: { 'items._id': itemObjectID }, then: true, else: false },
      },
    },
  },    

但是 MongoDB 给了我一个错误:

MongoError: FieldPath field names may not contain '.'.

不知道为什么它不起作用,有什么帮助或想法吗?非常感谢!

【问题讨论】:

    标签: node.js mongodb mongodb-query aggregation-framework


    【解决方案1】:

    这里缺少的是 $eq 聚合运算符,它检查相等的条件。

    如果你想检查ObjectId,你可以在这里尝试下面的聚合,那么你需要输入mongoose.Types.ObjectId(_id)

    db.collection.aggregate([
      { "$unwind": "$items" },
      { "$addFields": {
        "items.selected": {
          "$eq": [
            1111,
            "$items._id"
          ]
        }
      }},
      { "$group": {
        "_id": "$_id",
        "name": { "$first": "$name" },
        "items": {
          "$push": {
            "_id": "$items._id",
            "selected": "$items.selected"
          }
        }
      }}
    ])
    

    会给出以下输出

    [
      {
        "_id": ObjectId("5a934e000102030405000000"),
        "items": [
          {
            "_id": 1111,
            "selected": true
          },
          {
            "_id": 2222,
            "selected": false
          }
        ],
        "name": "Name"
      }
    ]
    

    您可以查看here

    【讨论】:

    • 谢谢!在您的帮助下,我找到了我的解决方案。由于代码部分很大,我将其发布为我自己问题的答案...谢谢
    【解决方案2】:

    @Ashish:非常感谢您的帮助!您的回答帮助我为我构建了正确的查询:

      db.collection.aggregate([
      {
        $unwind: "$items"
      },
      {
        $project: {
          "items.name": 0,
          "birthday": 0
        }
      },
      {
        "$addFields": {
          "items.selected": {
            "$eq": [
              1111,
              "$items._id"
            ]
          }
        }
      },
      {
        $group: {
          _id: "$_id",
          "name": {
            "$first": "$name"
          },
          items: {
            $push: "$items"
          }
        }
      },
      {
        $match: {
          "items._id": {
            $eq: 1111
          }
        }
      },
    ])
    

    并导致如下所示的结果:

    [
      {
        "_id": ObjectId("5a934e000102030405000000"),
        "items": [
          {
            "_id": 1111,
            "selected": true
          },
          {
            "_id": 2222,
            "selected": false
          }
        ],
        "name": "Name"
      }
    ]
    

    【讨论】:

    • 嗨@Vizari,实际上你在这里做错的是$match$project...$match应该尽快使用,$project应该使用在聚合结束...而且您不需要在这里使用$project...您可以看到我的更新答案...
    • 嗨@Ashish,感谢您的回复。如果我不使用$project,我必须在我的结果中添加我想要的根文档的每个字段,并带有“名称”:{ "$first": "$name" }$push: "$items"for my nested object?。如果我将“$match”放在聚合的开头,我的结果中只有与该条件匹配的嵌套对象,但我需要所有这些对象,因为它们必须标记为“selected:false”
    猜你喜欢
    • 2018-10-27
    • 2012-08-12
    • 2019-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-01
    • 1970-01-01
    相关资源
    最近更新 更多