Преобразование строки в формат даты в массивах в MongoDB с помощью $dateFromString (наличие NaT)

Я пытаюсь преобразовать некоторую строку в формат даты с помощью MongoDB, используя $dateFromString. Однако, поскольку интересующие меня поля являются частью массива, я столкнулся с некоторыми проблемами при написании правильного кода. После этого обсуждения я попытался преобразовать строку актуальный формат. К сожалению, поля даты не всегда заполнены, иногда строка-дата (из-за отсутствия информации) оказывается NaT. Поэтому код, который я вернул, выдал следующую ошибку:

[js] uncaught exception: Error: command failed: {
            "ok" : 0,
            "errmsg" : "Error parsing date string 'Na'; 0: passing a time zone identifier as part of the string is not allowed 'N'",
            "code" : 241,
            "codeName" : "ConversionFailure"
    } : aggregate failed :

Вот пример моих документов:

[
    {
        "cflavoratore_crip": "00753DCF12E23D69F5E4CF95A04700AC",
        "annonascita": 1978,
        "codgenere": "M",
        "attivazioni": [
            {
                "cfdatore_crip": "6C1DFCC6596D219ADAAE5ABA9C853015",
                "rapporto_datainizio": "2009-12-30 00:00:00",
                "codregionelavoro": "Puglia",
                "codprovincialavoro": 73.0,
                "dtcessazioneeffettiva": "2010-01-01 00:00:00",
                "dtfineprevista": "2010-01-01 00:00:00"
            }
        ]
    },
    {
        "cflavoratore_crip": "0083422D66F4C2EAEBB1B296DF86975A",
        "annonascita": 1985,
        "codgenere": "M",
        "attivazioni": [
            {
                "cfdatore_crip": "27E232D343049C13213C4DCA5756B5A5",
                "rapporto_datainizio": "2015-07-29 00:00:00",
                "codregionedomicilio": "Sicilia",
                "codprovincialavoro": 87.0,
                "dtcessazioneeffettiva": "2015-08-13 00:00:00",
                "dtfineprevista": "NaT"
            }
        ]
    }
]

Переменные, которые я хочу преобразовать в формат даты, следующие: rapporto_datainizio, dtcessazioneeffettiva и dtfineprevista. Однако в некоторых случаях они могут принимать значение NaT. Думаю, мне следует использовать $cond для решения этой проблемы (?).

До сих пор я использовал следующий код (название коллекции: datacico). Довольно долго...

db.datacico.aggregate([
    {
        '$addFields': {
            'attivazioni': {
                '$map': {
                    'input': '$attivazioni', 
                    'as': 'attivazioni', 
                    'in': {  
                        'cfdatore_crip': '$$attivazioni.cfdatore_crip',
                        'rapporto_datainizio': {
                            '$toDate': {
                                '$substr': [
                                    '$$attivazioni.rapporto_datainizio', 0, {
                                        '$subtract': [ 
                                            {
                                                '$strLenCP': '$$attivazioni.rapporto_datainizio'
                                            }, 1
                                        ]
                                    }
                                ]
                            }     
                        }, 
                        'codregionedomicilio': '$$attivazioni.codregionedomicilio', 
                        'codregionelavoro': '$$attivazioni.codregionelavoro',
                        'codprovincialavoro': '$$attivazioni.codprovincialavoro',                 
                        'dtcessazioneeffettiva': {
                            '$toDate': {
                                '$substr': [
                                    '$$attivazioni.dtcessazioneeffettiva', 0, {
                                        '$subtract': [
                                            {
                                                '$strLenCP': '$$attivazioni.dtcessazioneeffettiva'
                                            }, 1
                                        ]
                                    }
                                ]
                            }     
                        },                    
                        'dtfineprevista': {
                            '$toDate': {
                                '$substr': [
                                    '$$attivazioni.dtfineprevista', 0, {
                                        '$subtract': [
                                            {
                                                '$strLenCP': '$$attivazioni.dtfineprevista'
                                            }, 1
                                        ]
                                    }
                                ]
                            }     
                        }
                    }
                }
            }
        }
    }, {
        '$out': 'datacico'
    }
])

Тем не менее, я думаю, что с использованием $dateFromString это могло бы стать намного проще и короче. Я использовал следующий, но он не работает. В данном случае я ссылался только на файл rapporto_datainizio.

db.datacico.aggregate([{
"$project": {
    "attivazioni": {
      "$map": {
        "input": "$attivazioni",
       "in": {
         "rapporto_datainizio": {
            "$dateFromString": {
              "dateString": '$rapporto_datainizio'
             }
           }
         }
       }
     }
   }
}])

Я надеюсь, что кто-то может дать мне несколько советов. Заранее спасибо!


person Nicola Caravaggio    schedule 19.11.2019    source источник


Ответы (1)


Этот запрос агрегации будет работать. Обратите внимание, что значение «NaT» нельзя преобразовать в объект Date. Итак, какова ваша логика по этому поводу? В запросе я заменил «NaT» сегодняшней датой (см. $cond в $map); но вы можете заполнить его тем, что нужно вашему приложению.

db.dates.aggregate( [
{ $project: { 
       attivazioni: { 
           $map: {
               input: "$attivazioni",
                  as: "att",
                  in: {
                      "cfdatore_crip" : "$$att.cfdatore_crip",
                      "rapporto_datainizio" : { $toDate: "$$att.rapporto_datainizio" },
                      "codregionelavoro" : "$$att.codregionelavoro",
                      "codprovincialavoro" : "$$att.codprovincialavoro",
                      "dtcessazioneeffettiva" : { $toDate: "$$att.dtcessazioneeffettiva" },
                      "dtfineprevista" : { $cond: [ { $eq: [ "$$att.dtfineprevista", "NaT" ] }, 
                                                     ISODate(), 
                                                     { $toDate: "$$att.dtfineprevista" } 
                                                  ] 
                                           }
                     }
} } } },
] )
person prasad_    schedule 19.11.2019
comment
Спасибо @prasad_ за помощь! - person Nicola Caravaggio; 19.11.2019