В MongoDB, $dateFromString
Операторът на конвейера за агрегиране преобразува низ за дата/час в обект за дата.
Пример
Да предположим, че имаме колекция, наречена foo
със следните документи:
{ "_id" : 1, "bar" : "2020-12-31T23:30:25.123" } { "_id" : 2, "bar" : "2020-12-31" } { "_id" : 3, "bar" : "2020-12-31T23:30" }
Всички документи съдържат низ за дата/час.
Можем да изпълним следния код, за да върнем обект за дата от bar
полета в тези документи.
db.foo.aggregate([
{
$project: {
date: {
$dateFromString: {
dateString: '$bar'
}
}
}
}
])
Резултат:
{ "_id" : 1, "date" : ISODate("2020-12-31T23:30:25.123Z") } { "_id" : 2, "date" : ISODate("2020-12-31T00:00:00Z") } { "_id" : 3, "date" : ISODate("2020-12-31T23:30:00Z") }
Всички низове за дата/час са преобразувани в обект за дата.
Също така промених името на полето от bar
до date
.
Посочете формат
Можете да предоставите по избор format
аргумент, за да посочите формата на низа за дата/час, който се предоставя. Спецификацията на формата може да бъде всеки низов литерал, съдържащ 0 или повече спецификатори на формат.
format
параметърът е наличен от MongoDB версия 4.0.
Форматът по подразбиране е %Y-%m-%dT%H:%M:%S.%LZ
, което използва предишният пример.
Да предположим, че вмъкваме следния документ в нашата колекция:
{ "_id" : 4, "bar" : "07/08/2020" }
В този случай датата може да бъде 7-ми ден от 8-ия месец или 8-ми ден от 7-ия месец, в зависимост от използвания локал.
Можем да използваме спецификация на формат, за да посочим точно кой трябва да бъде.
Пример:
db.foo.aggregate([
{ $match: { _id: 4 } },
{
$project: {
date: {
$dateFromString: {
dateString: '$bar',
format: "%m/%d/%Y"
}
}
}
}
])
Резултат:
{ "_id" : 4, "date" : ISODate("2020-07-08T00:00:00Z") }
В този случай уточнихме, че това е 8-ми ден от 7-ия месец.
Ето го отново, но този път сменяме деня и месеца.
db.foo.aggregate([
{ $match: { _id: 4 } },
{
$project: {
date: {
$dateFromString: {
dateString: '$bar',
format: "%d/%m/%Y"
}
}
}
}
])
Резултат:
{ "_id" : 4, "date" : ISODate("2020-08-07T00:00:00Z") }
Този път се тълкува като 7-ми ден от 8-ия месец.
Вижте MongoDB $dateFromString
Форматни спецификатори за списък с валидни спецификатори на формат.
Формат на датата на седмицата по ISO
Има няколко спецификатора на формат, които ви позволяват да посочите дати с помощта на ISO 8601 формат.
По-специално, можете да използвате:
Определител на формата | Изход |
---|---|
%G | Година във формат ISO 8601 |
%u | Номер на деня от седмицата във формат ISO 8601 (1-понеделник, 7-неделя) |
%V | Седмица на годината във формат ISO 8601 |
Да предположим, че имаме документ, който изглежда така:
{ "_id" : 5, "bar" : "7-8-2020" }
Бихме могли да тълкуваме тази дата като 7-ми ден от седмицата по ISO, последван от 8-та седмица по ISO на годината, последван от годината.
Като това:
db.foo.aggregate([
{ $match: { _id: 5 } },
{
$project: {
date: {
$dateFromString: {
dateString: '$bar',
format: "%u-%V-%G"
}
}
}
}
])
Резултат:
{ "_id" : 5, "date" : ISODate("2020-02-23T00:00:00Z") }
Посочете часова зона
Можете да посочите часова зона, която да използвате с $dateFromString
оператор.
Часовата зона може да бъде определена с помощта на идентификатора на часовата зона на Олсън (напр. "Europe/London"
, "GMT"
) или отместването на UTC (напр. "+02:30"
). , "-1030"
).
Идентификатор на часовата зона на Олсън
Ето пример, който извежда низа за дата в три различни часови зони, всяка от които използва идентификаторите на часовата зона на Olson:
db.foo.aggregate([
{ $match: { _id: 1 } },
{
$project: {
utc: {
$dateFromString: {
dateString: '$bar',
timezone: "UTC"
}
},
honolulu: {
$dateFromString: {
dateString: '$bar',
timezone: "Pacific/Honolulu"
}
},
auckland: {
$dateFromString: {
dateString: '$bar',
timezone: "Pacific/Auckland"
}
}
}
}
]).pretty()
Резултат:
{ "_id" : 1, "utc" : ISODate("2020-12-31T23:30:25.123Z"), "honolulu" : ISODate("2021-01-01T09:30:25.123Z"), "auckland" : ISODate("2020-12-31T10:30:25.123Z") }
Изместване на UTC
Ето пример, който използва UTC отместване.
db.foo.aggregate([
{ $match: { _id: 1 } },
{
$project: {
"date+00:00": {
$dateFromString: {
dateString: '$bar',
timezone: "+00:00"
}
},
"date-10:00": {
$dateFromString: {
dateString: '$bar',
timezone: "-10:00"
}
},
"date+12:00": {
$dateFromString: {
dateString: '$bar',
timezone: "+12:00"
}
}
}
}
]).pretty()
Резултат:
{ "_id" : 1, "date+00:00" : ISODate("2020-12-31T23:30:25.123Z"), "date-10:00" : ISODate("2021-01-01T09:30:25.123Z"), "date+12:00" : ISODate("2020-12-31T11:30:25.123Z") }
Ако използвате timezone
параметър, низът от дата не може да бъде добавен със Z, за да посочи времето на Зулу (UTC часова зона). Например низът за дата не може да бъде 2020-12-31T23:30:25.123Z
когато използвате параметъра часова зона.
Също така, не включвайте информация за часовата зона в низа за дата, когато използвате параметъра за часова зона.
onNull
Параметър
onNull
параметърът може да се използва, за да посочи какво да върне, ако датата е нула или не съществува.
Стойността, предоставена на onNull
параметърът може да бъде всеки валиден израз.
Да предположим, че имаме документ като този:
{ "_id" : 6, "bar" : null }
Можем да използваме onNull
по следния начин:
db.foo.aggregate([
{ $match: { _id: 6 } },
{
$project: {
date: {
$dateFromString: {
dateString: '$bar',
onNull: "No valid date was supplied"
}
}
}
}
])
Резултат:
{ "_id" : 6, "date" : "No valid date was supplied" }
В този случай датата е null
и така изходният документ включва низа, който предоставих за onNull
параметър.
onError
Параметър
По желание можете да използвате onError
параметър за предоставяне на израз за извеждане в случай на възникване на грешка.
Да предположим, че нашата колекция съдържа следния документ:
{ "_id" : 7, "bar" : "21st Dec, 2030" }
Въпреки че има дата в bar
поле, това не е валиден низ за дата/час и следователно ще причини грешка, ако използваме dateFromString
за да се опитате да го конвертирате в обект за дата.
Пример за грешка:
db.foo.aggregate([
{ $match: { _id: 7 } },
{
$project: {
date: {
$dateFromString: {
dateString: '$bar'
}
}
}
}
])
Резултат:
Error: command failed: { "ok" : 0, "errmsg" : "an incomplete date/time string has been found, with elements missing: \"21st Dec, 2030\"", "code" : 241, "codeName" : "ConversionFailure" } : aggregate failed : [email protected]/mongo/shell/utils.js:25:13 [email protected]/mongo/shell/assert.js:18:14 [email protected]/mongo/shell/assert.js:618:17 [email protected]/mongo/shell/assert.js:708:16 [email protected]/mongo/shell/db.js:266:5 [email protected]/mongo/shell/collection.js:1046:12 @(shell):1:1
Това е неприятна грешка.
Можем да използваме onError
параметър, за да изглежда по-добре:
db.foo.aggregate([
{ $match: { _id: 7 } },
{
$project: {
date: {
$dateFromString: {
dateString: '$bar',
onError: "An error occurred while parsing the date string"
}
}
}
}
])
Резултат:
{ "_id" : 7, "date" : "An error occurred while parsing the date string" }
Вижда се като onNull
и onError
параметрите ни позволяват да върнем действителните документи, те ни позволяват да върнем множество документи, без да се притесняваме, че един лош документ ще спре цялата операция.
Пример:
db.foo.aggregate([
{
$project: {
date: {
$dateFromString: {
dateString: '$bar',
onNull: "The date was either empty or null",
onError: "An error occurred while parsing the date string"
}
}
}
}
])
Резултат:
{ "_id" : 1, "date" : ISODate("2020-12-31T23:30:25.123Z") } { "_id" : 2, "date" : ISODate("2020-12-31T00:00:00Z") } { "_id" : 3, "date" : ISODate("2020-12-31T23:30:00Z") } { "_id" : 4, "date" : ISODate("2020-07-08T00:00:00Z") } { "_id" : 5, "date" : ISODate("2020-08-07T00:00:00Z") } { "_id" : 6, "date" : "The date was either empty or null" } { "_id" : 7, "date" : "An error occurred while parsing the date string" }