Если «строка» находится в «лексическом» формате ISO, как в "2018-05-15T20:59:31.502Z"
, то вы «могли бы» получить $substr
частей:
Subjects.aggregate([
{ "$group": {
"_id": { "$substr": ["$metrics."+metric,0,10] },
"count": { "$sum": 1 }
}}
])
Если у вас есть MongoDB 3.6, то вы «могли бы» использовать $dateFromString
, чтобы фактически преобразовать это в формат даты BSON, но вы, вероятно, хотите аналогичным образом обрезать эту строку аналогичным образом для любой даты Вы действительно хотите округлить:
Subjects.aggregate([
{ "$group": {
"_id": {
"$dateFromString": {
"dateString": { "$substr": ["$metrics."+metric,0,10] }
}
},
"count": { "$sum": 1 }
}}
])
MongoDB 4.0 имеет $toDate
для немного короче и делает то же самое преобразование даты BSON:
Subjects.aggregate([
{ "$group": {
"_id": {
"$toDate": { "$substr": ["$metrics."+metric,0,10] }
},
"count": { "$sum": 1 }
}}
])
Но основной факт в том, что если ваша «строка» на самом деле не выглядит так и не может быть по-разному разбита на части строки поддерживаемыми операторами, тогда вам, как правило, гораздо лучше преобразовать даты, хранящиеся в вашем Во-первых, коллекции должны быть настоящими. Даты BSON.
Вместо этого рекомендуется «выполнить» преобразование данных. Оболочки mongo
должно быть достаточно для запуска одноразовых преобразований:
var batch = [];
db.subjects.find().forEach(doc => {
var fields = Object.keys(doc.metrics).map(k => ({
['metrics.'+k]: new Date(doc.metrics[k]),
})).reduce((acc,curr) => Object.assign(acc,curr),{});
batch.push({
"updateOne": {
"filter": doc._id",
"update": { "$set": fields }
}
});
if ( batch.length > 1000 ) {
db.subjects.bulkWrite(batch);
batch = []
}
})
if ( batch.length > 0 ) {
db.subjects.bulkWrite(batch);
batch = [];
}
Это основной процесс. Конечно, если ваши «строки» не в формате ISO или не подходят для передачи в Date()
для преобразования, тогда вам действительно нужно принять другие меры.
По крайней мере, дата BSON представляет собой 8-битную структуру данных с «внутренним» числовым представлением, где в качестве эквивалентной «строки» она составляет не менее 24 байтов и даже больше со словами, обозначающими дни и месяцы. При работе с базой данных имеет смысл сохранять данные, которые по существу имеют «числовой» характер, в этой форме.
Мой совет - преобразовать данные, и, возможно, при импорте или, если вы не можете это обработать, то хотя бы один раз загрузить в коллекцию. Лучше пытаться работать со строками для чего-то, что они на самом деле не предназначены.
Примечание $substr
считается устаревшим и фактически теперь псевдонимы $substrBytes
, или вы можете использовать $substrCP
в зависимости от на фактическое кодирование данных. Более старые выпуски MongoDB до 3.2 имеют только выражение $substr
.