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

#mongodb

Вопрос:

В базе данных mongo у меня есть коллекция, касающаяся зданий («центрос»), которые содержат устройства («диспозитивы»), и эти устройства содержат датчики («сенсоры»). Я пытаюсь обновить один из этих датчиков. Здания идентифицируются по их «_id», устройства-по их «uid», а датчики-по их «имени переменной» («переменная»). Я уже пробовал следовать некоторым примерам, найденным в StackOverflow, но не преуспел.

Это мое приближение:

 db.collection.update({
  "uid": "e898b585-d855-4017-9fe4-0644360f9d1b"
},
{
  "$set": {
    "dispositivos.$[dispositivo].sensores.$[sensor]": {
      "variable": "Plutonio",
      "unidad": "yuyuyuyuuyu"
    }
  }
},
{
  "multi": false,
  "upsert": false,
  arrayFilters: [
    {
      "dispositivo.uid": "e898b585-d855-4017-9fe4-064386kkkkkk",
      "sensor.variable": "intensidad"
    }
  ]
})
 

Но это дает мне следующую ошибку:

 fail to run update: multiple write errors: [{write errors: [{Error parsing array filter :: caused by :: Expected a single top-level field name, found 'sensor' and 'dispositivo'}]}, {<nil>}]
 

Там у вас есть живой образец: https://mongoplayground.net/p/KrWw2WxkSch

Это образец моей коллекции:

 [
  {
    "uid": "e898b585-d855-4017-9fe4-0644360f9d1b",
    "nombre": "Colegio Rio Piles",
    "tipo": "Colegio",
    "direccion": {
      "calle": "Paseo Dr. Fleming, 1109",
      "codigoPostal": "33204",
      "municipio": "Gijon",
      "provincia": "Asturias",
      "ubicacion": {
        "latitud": "43.5351406",
        "longitud": "-5.6345379"
      }
    },
    "horario": {
      "apertura": "09:00",
      "cierre": "22:00"
    },
    "dispositivos": [
      {
        "uid": "e898b585-d855-4017-9fe4-064386055555",
        "descripcion": "",
        "tipo": "ANALIZADOR_RED",
        "adquisicion": "30s",
        "sensores": [
          {
            "variable": "voltaje",
            "unidad": "V"
          },
          {
            "variable": "intensidad",
            "unidad": "A"
          }
        ]
      },
      {
        "uid": "e898b585-d855-4017-9fe4-064386kkkkkk",
        "descripcion": "",
        "tipo": "CONTADOR_AGUA",
        "adquisicion": "30s",
        "sensores": [
          {
            "variable": "caudal",
            "unidad": "l/s"
          }
        ]
      }
    ]
  }
]
 

Спасибо ДЖО за помощь. Это и есть решение:

 db.collection.update({
  "uid": "e898b585-d855-4017-9fe4-0644360f9d1b"
},
{
  "$set": {
    "dispositivos.$[dispositivo].sensores.$[sensor]": {
      "variable": "Plutonio",
      "unidad": "yuyuyuyuuyu"
    }
  }
},
{
  "multi": false,
  "upsert": false,
  arrayFilters: [
    {
      "dispositivo.uid": "e898b585-d855-4017-9fe4-064386055555"
    },
    {
      "sensor.variable": "intensidad"
    }
  ]
})
 

Ответ №1:

Каждый фильтр массива должен быть своим собственным объектом в массиве, например

  arrayFilters: [
    {
      "dispositivo.uid": "e898b585-d855-4017-9fe4-064386kkkkkk"
    },
    {
      "sensor.variable": "intensidad"
    }
  ]