Как скопировать значение между полями внутри каждого объекта во встроенном массиве объектов в MongoDB?

#mongodb #aggregate

#mongodb #агрегат

Вопрос:

В моей коллекции «сборки» каждый документ содержит встроенный массив объектов, называемый «список деталей»:

 {
 "_id" : ObjectId("0001"),
 "pn" : "01",
 "title" : "MyAssembly",
 "partlist" : [ 
 {
    "id" : "",
    "pn" : "1234",
    "desc" : "myPart1",
 }, 
 {
    "id" : "",
    "pn" : "5678",
    "desc" : "myPart2",
 }]
}
 

Внутри каждого объекта мне нужно скопировать значение из ‘partlist.pn » внутрь «partlist.id «. Я использовал:

 db.assemblies.aggregate([{$set:{"partlist.id":"$partlist.pn"}}])
 

надеясь достичь этого:

 {
 "_id" : ObjectId("0001"),
 "pn" : "01",
 "title" : "MyAssembly",
 "partlist" : [ 
 {
    "id" : "1234",
    "pn" : "1234",
    "desc" : "myPart1",
 }, 
 {
    "id" : "5678",
    "pn" : "5678",
    "desc" : "myPart2",
 }]
}
 

Вместо этого он вернул в ‘id’ массив ВСЕХ значений ‘pn’ в ‘partlist’:

 {
 "_id" : ObjectId("0001"),
 "pn" : "01",
 "title" : "MyAssembly",
 "partlist" : [ 
 {
    "id" : [ 
        "1234",
        "5678"
     ],
    "pn" : "1234",
    "desc" : "myPart1",
 }, 
 {
    "id" : [ 
        "1234",
        "5678"
     ],
    "pn" : "5678",
    "desc" : "myPart2",
 }]
}
 

Каков правильный синтаксис для копирования одного значения внутри каждого объекта?

Комментарии:

1. Это id pn и desc все, что у вас есть в виде полей, или есть еще поля?

Ответ №1:

Что вы можете сделать, так это использовать $map для изменения каждого элемента и измерения id с помощью $mergeObject

 db.collection.aggregate([
  {
    $addFields: {
      "partlist": {
        $map: {
          input: "$partlist",
          in: {
            "$mergeObjects": [
              "$this",
              {
                id: "$this.pn"
              }
            ]
          }
        }
      }
    }
  }
])
 

Рабочая игровая площадка Mongo

Комментарии:

1. Спасибо, Варман, это сработало. Так много нужно изучить и так мало времени…

2. @user1925590 подумайте о том, чтобы принять ответ, который может помочь другим в будущем

3. Конечно. Как мне это сделать?

Ответ №2:

  • Если pn он не существует, он извлекает исходный объект.
 db.collection.aggregate([
  {
    $addFields: {
      partlist: {
        $map: {
          input: "$partlist",
          as: "p",
          in: {
            $cond: [
              "$p.pn",
              {
                $mergeObjects: [
                  "$p",
                  {
                    "id": "$p.pn"
                  }
                ]
              },
              "$p"
            ]
          }
        }
      }
    }
  }
])
 

Игровая площадка