Mongodb concat int и строка
Я пытаюсь проецировать FileName и FileSize для всех моих файлов в моей коллекции с размером 50 МБ и больше, но я не могу объединить тип FileSize, поскольку он имеет тип Int
Я хочу, чтобы Проекция была
{
"result" : [
{
"_id" : ObjectId("5652c399a21dad0bb01b6308"),
"FileName" : "1234567890.xml",
"FileSize" : "11.06 MB"
},
{
"_id" : ObjectId("5652c399a21dad0bb01b630f"),
"FileName" : "2468101214.xml",
"FileSize" : "320.48 MB"
},
{
"_id" : ObjectId("5652c399a21dad0bb01b631f"),
"FileName" : "3691215180.xml",
"FileSize" : "12.95 MB"
}
}
но пока я могу вернуть только следующее
{
"result" : [
{
"_id" : ObjectId("5652c399a21dad0bb01b6308"),
"FileName" : "1234567890.xml",
"FileSize" : 11.0610504150390630
},
{
"_id" : ObjectId("5652c399a21dad0bb01b630f"),
"FileName" : "2468101214.xml",
"FileSize" : 320.4827098846435500
},
{
"_id" : ObjectId("5652c399a21dad0bb01b631f"),
"FileName" : "3691215180.xml",
"FileSize" : 12.9519605636596680
}
}
мой запрос:
db.MyCollection.aggregate(
// Pipeline
[
// Stage 1
{
$match: {
FileSize: {$gte: 5000000}
}
},
// Stage 2
{
$project: {
FileName: 1,
FileSize: {$divide: ["$FileSize", 1048576]}
}
},
// Stage 3
{
$project:{
FileName:1,
FileSize:{$concat:["$FileSize", "MB"]}
}
}
как объединить поле FileSize и "MB"?
3 ответов
трюк здесь заключается в использовании $substr
для преобразования в строку и несколько дополнительных функций для обработки десятичной точности:
{ "$project": {
"FileName": 1,
"FileSize": {
"$concat": [
{ "$substr": [
{ "$subtract": [ "$FileSize", { "$mod": [ "$FileSize", 1 ] }]},
0,
-1
]},
{ "$substr": [ { "$mod": [ "$FileSize", 1 ] }, 1, 3] },
" MB",
]
}
}}
или еще лучше, объединить в один $project
, либо с помощью $let
в версиях, более поздних, чем MongoDB 2.6,или в случае необходимости. Один этап трубопровода более эффективен, чем два:
{ "$project": {
"FileName": 1,
"FileSize": {
"$let": {
"vars": {
"FileSize": { "$divide": [ "$FileSize", 1048576 ] }
},
"in":{
"$concat": [
{ "$substr": [
{ "$subtract": [ "$$FileSize", { "$mod": [ "$$FileSize", 1 ] }]},
0,
-1
]},
{ "$substr": [ { "$mod": [ "$$FileSize", 1 ] }, 1, 3] },
" MB",
]
}
}
}
}}
до тех пор, пока вы разбиваете число в десятичной точке ( через $mod
) вы можете бросить аргумент "length" на остальную часть строки, чтобы иметь дело с числами длины арбитра. С "остатком", отделенным от использования $mod
длина строки до двух знаков после запятой всегда "три", начиная, конечно, со второй позиции, чтобы пропустить ведущий 0
.
возвращает именно то, что вы просили:
{
"_id" : ObjectId("5652c399a21dad0bb01b6308"),
"FileName" : "1234567890.xml",
"FileSize" : "11.06 MB"
}
{
"_id" : ObjectId("5652c399a21dad0bb01b630f"),
"FileName" : "2468101214.xml",
"FileSize" : "320.48 MB"
}
{
"_id" : ObjectId("5652c399a21dad0bb01b631f"),
"FileName" : "3691215180.xml",
"FileSize" : "12.95 MB"
}
Добавить Этап 2.5: P
{
$project:{
FileName:1,
FileSize:{$substr:["$FileSize", 0, -1 ]}
}
}
FileSize-это целое число, и нет операции преобразования его в строку. Таким образом, вы можете использовать hack и использовать substr для преобразования его в string, 0 для запуска и -1 остальной части строки.
теперь это возможно в MongoDB v4.0 использование $toString оператор, который преобразует значение в строку:
db.col.aggregate([
{
$project: {
FileSize: { $concat: [ { $toString: "$FileSize" }, " MB" ] }
}
}
])