MongoDB: добавить новое поле в существующий поддокумент после этапа $ look или ответ на поиск слияния с основным документом - PullRequest
1 голос
/ 12 марта 2020

Я хочу новое поле "isActive" внутри вложенного документа modifierStatus, которое поступает из элементов модификаторов коллекции.

элементов модификаторов коллекции:

{
    "_id" : ObjectId("5e6a5a0e6d40624b12453a67"),
    "modifierName" : "xxx",
    "isActive" : 1
}
{
    "_id" : ObjectId("5e6a5a0e6d40624b12453a6a"),
    "modifierName" : "yyy",
    "isActive" : 0
}

favouritrinks коллекция:

{
  "alcoholName" : "whiskey",
  "modifierList" : [{
       "_id" : ObjectId("5e6a5a0e6d40624b12453a61"), 
       "modifierId" : ObjectId("5e6a5a0e6d40624b12453a67"),
       "modifierName" : "xxx",
     }
     {
       "_id" : ObjectId("5e6a5a0e6d40624b12453a66"),
       "modifierId" : ObjectId("5e6a5a0e6d40624b12453a6a"),
       "modifierName" : "yyy",
     }]
 }

мой запрос:

db.getCollection('favoritedrinks').aggregate([
  { "$sort": { "alcoholName": 1 } },
  {"$lookup": {
      "from": "modifieritems",
      localField: 'modifierList.modifierId', 
      foreignField: '_id', 
      as: 'modifier'
  }},
  {
     $project:{
        "alcoholName" : "$alcoholName",
        "modifierStatus":"$modifier", 
     }
   },
 ]);

Но мой ожидаемый результат:

{
     "alcoholName" : "Whiskey",
      "modifierStatus" : [
        {
            "_id" : ObjectId("5e6a5a0e6d40624b12453a61"),
            "modifierId" : ObjectId("5e6a5a0e6d40624b12453a67"), 
            "modifierName" : "xxx",
            "isActive" : 1,
        },
        {
            "_id" : ObjectId("5e6a5a0e6d40624b12453a66"),
            "modifierId" : ObjectId("5e6a5a0e6d40624b12453a6a"),
            "modifierName" : "yyy",
            "isActive" : 0,
        }
    ]
}

любой, пожалуйста, помогите мне

Ответы [ 2 ]

1 голос
/ 12 марта 2020

Попробуйте этот запрос:

Обновите с новым требованием:

db.favoritedrinks.aggregate([
  {
    "$sort": {
      "alcoholName": 1
    }
  },
  {
    "$lookup": {
      "from": "modifieritems",
      localField: "modifierList.modifierId",
      foreignField: "_id",
      as: "modifierStatus"
    }
  },
  {
    $addFields: {
      modifierStatus: {
        $map: {
          input: "$modifierList",
          as: "m",
          in: {
            $mergeObjects: [
              {
                $arrayElemAt: [ /** As filter would only get one object (cause you'll have only one matching doc in modifieritems coll for each "modifierList.modifierId", So getting first element out of array, else you need to take this array into an object & merge that field to particular object of 'modifierList') */ 
                  {
                    $filter: {
                      input: "$modifierStatus",
                      cond: {
                        $eq: [
                          "$$this._id",
                          "$$m.modifierId"
                        ]
                      }
                    }
                  },
                  0
                ]
              },
              "$$m"
            ]
          }
        }
      }
    }
  },
  {
    $project: {
      modifierStatus: 1,
      alcoholName: 1,
      _id: 0
    }
  }
])

Тест: MongoDB-Playground

Старый:

db.favoritedrinks.aggregate([
    {
        "$sort": {
            "alcoholName": 1
        }
    },
    {
        $lookup: {
            from: "modifieritems",
            let: {
                id: "$modifierList.modifierId"
            },
            pipeline: [
                {
                    $match: { $expr: { $in: ["$_id", "$$id"] } }
                },
                /** Adding a new field modifierId(taken from _id field of modifieritems doc) 
                 * to each matched document from modifieritems coll */
                {
                    $addFields: {
                        modifierId: "$_id"
                    }
                }
            ],
            as: "modifierStatus"
        }
    },
    /** By mentioning 0 to particular fields to remove them & retain rest all other fields */
    {
        $project: {
            modifierList: 0,
            _id: 0
        }
    }
])

Тест: MongoDB-Playground

0 голосов
/ 12 марта 2020

Если вы хотите, чтобы $project включал текущее значение поля, сохраняя то же имя поля, вам нужно только указать :1. Когда вы используете "$field", вы явно устанавливаете значение, которое перезапишет любое существующее значение.

Попробуйте сделать прогноз:

{
     $project:{
        "alcoholName" : 1,
        "modifier.isActive": 1,
        "modifier.modifierName": 1 
     }
}
...