I am trying to convert some string into date format with MongoDB using $dateFromString. However, since my fields of interested are part of an array, I have encountered some problems in writing down the correct code. Following the this discussion, I attempted to convert string to date format. Unfortunately, the date fields are not always filled, sometime the string-date (because of an absence of information) is NaT. Therefore, the code that I returned the following error:
[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 :
Here there is an example of my documents:
[
{
"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"
}
]
}
]
The variables that I want to convert into date format are the following: rapporto_datainizio, dtcessazioneeffettiva, and dtfineprevista. However, is some case they can assume the value of NaT. I guess I should use the $cond to solve this problem (?).
So far the code that I used has been the following one (collection name: datacico). Quite long...
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'
}
])
Nonetheless, I think that with the use of $dateFromString it could become quite more easier and shorter. I used the following one, but it does not work. In this case I referred only to the filed of rapporto_datainizio.
db.datacico.aggregate([{
"$project": {
"attivazioni": {
"$map": {
"input": "$attivazioni",
"in": {
"rapporto_datainizio": {
"$dateFromString": {
"dateString": '$rapporto_datainizio'
}
}
}
}
}
}
}])
I hope someone could give me some hints. Thank you in advance!
This aggregation query will work. Note the value of "NaT" cannot be converted to a Date
object. So, what is your logic about it? In the query I substituted "NaT" with today's date (see the $cond
in the $map
); but you can fill it with what your application needs.
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" }
]
}
}
} } } },
] )