WedX - журнал о программировании и компьютерных науках

MongoDB $set элемент в массиве, который не существует с объектом, поскольку элемент приводит к объекту вместо массива

Обновление элементов внутри массива объясняется здесь:

https://docs.mongodb.com/manual/reference/operator/update/set/#set-elements-in-arrays

Но в документах отсутствует случай, когда массив еще не существует в документе. Пример:

Если есть этот документ:

{
  _id: 'some-id',
  otherprops: 'value'
}

И я хочу, чтобы это стало так:

{
  // ...
  settings: {
    friends: [
      {
        name: 'John Doe',
        age: 28
      }
    ]
  }
  // ...
}

В этой ситуации я не знаю, есть ли уже массив settings.friends. Итак, мой запрос выглядит так:

{
  $set: {
    'settings.friends.0.name': 'John Doe',
    'settings.friends.0.age': 28
  }
}

Однако документ приводит к следующему:

{
  // ...
  settings: {
    friends: {
      0: {
        name: 'John Doe',
        age: 28
      }
    }
  }
  // ...
}

Есть ли способ заставить mongodb создать массив вместо объекта в моем примере, но только с использованием точечной записи.

06.05.2019

  • Похоже, нет никакого способа сообщить MongoDB, какой должен быть результирующий тип данных. По умолчанию MongoDB преобразует путь с точечной нотацией в объект. Вы не можете привести путь к определенному типу, и нет явного синтаксиса, чтобы сообщить MongoDB, что предоставленный путь должен привести к массиву :( 09.07.2021

Ответы:


1

попробуй это.

{
    $addToSet: {
        "settings.friends": [
            {
                name: 'John Doe',
                age: 28
            }
        ]
    }
}
06.05.2019
  • В вашем случае я бы не стал делать это с точечной записью - но я хочу. Причина в том, что если я не делаю это с точечной нотацией, мне нужно проверить существующий документ, существует ли массив. Представьте, что вы хотите выполнить обновление документа только для одного свойства. Если бы я сделал то, что вы показали, другое свойство будет потеряно (если я не объединим его с существующим документом, чего я не хочу делать) 06.05.2019
  • Приведенный выше обновленный код удовлетворит ваши требования. 06.05.2019
  • Я только что увидел, что ваш пример тоже не то, что я блокировал. В вашем примере он всегда будет добавлять новый элемент в массив, но что, если объект в позиции массива 0 уже существует, и я хочу только обновить имя и возраст свойств вместо их добавления? Итак, проблема все та же: как решить, чтобы заставить mongodb использовать массивы при записи через точку? 09.05.2019
  • вы можете использовать $set вместо $addToset 09.05.2019
  • ... тогда у меня проблема, которую я описал в своем вопросе. Когда я делаю $set 'settings.firends.0.name', тогда вместо массива mongodb сохраняет объект. 10.05.2019

  • 2

    Это работает в версии mongodb v4.0.9. Я проверил ваш вариант использования на моей машине.

    db.collection.update(
      {
        "_id": 'your_key'
      },
      {
        "$set": {
          "settings.friends.0.name": "ABCD"
        }
      },
      {
        "upsert": "true"
      }
    )
    

    До обновления моя запись в коллекции была

    {
        "_id" : 2,
        "col1" : "val01",
        "settings" : {
            "friends" : [
                {
                    "name" : "Ramraj",
                    "age" : 28
                }
            ]
        }
    }
    

    После обновления моя запись в коллекции была

    {
        "_id" : 2,
        "col1" : "val01",
        "settings" : {
            "friends" : [
                {
                    "name" : "ABCD",
                    "age" : 28
                }
            ]
        }
    }
    
    06.05.2019
  • Это не совсем мой случай. В моем случае settings.friends не существует. В вашем случае он есть. 06.05.2019
  • Новые материалы

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..

    ИИ в аэрокосмической отрасли
    Каждый полет – это шаг вперед к великой мечте. Чтобы это происходило в их собственном темпе, необходима команда астронавтов для погони за космосом и команда технического обслуживания..


    Для любых предложений по сайту: [email protected]