Вставить новые поля в документ с указанным индексом массива в MongoDB - PullRequest
1 голос
/ 26 марта 2020

У меня есть следующая структура документа в коллекции MongoDB:

{
  "A" : [ {
      "B" : [ { ... } ]
  } ]
}

Я бы хотел обновить это до:

{
  "A" : [ {
      "B" : [ { ... } ],
      "x" : [],
      "y" : { ... }
  } ]
}

Другими словами, я хочу "x Поля "и" y "должны быть добавлены к первому элементу массива" A "без потери" B ".

Ответы [ 2 ]

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

Хорошо, поскольку в массиве A есть только один объект, который вы можете просто сделать, как показано ниже:

Образцы данных для сбора:

{
  "_id" : ObjectId("5e7c3cadc16b5679b4aeec26"),
  A:[
     {
       B: [{ abc: 1 }]
     }
    ]
}

Запрос:

/** Insert new fields into 'A' array's first object by index 0 */
db.collection.updateOne(
    {  "_id" : ObjectId("5e7c3f77c16b5679b4af4caf") },
    { $set: { "A.0.x":  [] , "A.0.y" : {abcInY :1 }} }
  )

Вывод:

{
    "_id" : ObjectId("5e7c3cadc16b5679b4aeec26"),
    "A" : [ 
        {
            "B" : [ 
                {
                    "abc" : 1
                }
            ],
            "x" : [],
            "y" : {
                "abcInY" : 1.0
            }
        }
    ]
}

Или с использованием позиционного оператора $ :

db.collection.updateOne(
    { _id: ObjectId("5e7c3cadc16b5679b4aeec26") , 'A': {$exists : true}},
    { $set: { "A.$.x":  [] , "A.$.y" : {abcInY :1 }} }
  )

Примечание: Результат будет таким же, но функционально при использовании позиционного оператора поля x & y вставляются в первый объект массива A только тогда, когда в этом поле существует поле A документы, если бы не этот позиционный запрос не вставил бы ничего (опционально вы можете проверить, что A также является условием массива, если это необходимо). Но когда вы выполняете обновления с использованием индекса 0, как в первом запросе, если A не существует в документе, тогда обновление создаст поле A, которое является объектом, и вставит в него поля (что может привести к несогласованности данных во всех документы с двумя типами поля A) - проверьте приведенный ниже результат первого запроса, когда A не существует.

{
    "_id" : ObjectId("5e7c3f77c16b5679b4af4caf"),
    "noA" : 1,
    "A" : {
        "0" : {
            "x" : [],
            "y" : {
                "abcInY" : 1.0
            }
        }
    }
}
0 голосов
/ 26 марта 2020

Тем не менее, я думаю, что смог получить anothe@whoami Спасибо за предложение, я думаю, что ваше первое решение должно работать. Тем не менее, я думаю, что смог найти другое решение, хотя я не уверен, что оно лучше или хуже (по производительности?), Чем то, что у вас здесь. Мое решение:

db.coll.update( { "_id" : ObjectId("5e7c4eb3a74cce7fd94a3fe7") }, [ { "$addFields" : { "A" : { "x" : [ 1, 2, 3 ], "y" : { "abc" } } } } ] )

Проблема в том, что если «A» имеет более одной записи массива, то это обновит все элементы в «A», что не является чем-то, что я хотеть. Просто из любопытства есть ли способ ограничить это решение только первой записью в «А»?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...