web-dev-qa-db-ja.com

Mongodb concat intおよびstring

50 mb以上のサイズでコレクション内のすべてのファイルのFileNameとFileSizeを投影しようとしていますが、タイプ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"フィールドを連結するにはどうすればよいですか?

20
Jaun Lloyd

ここでの秘訣は、文字列への変換を行うために $substr を使用することと、小数点の精度を処理するためのいくつかの小さな追加機能です。

    { "$project": {
        "FileName": 1,
        "FileSize": {
            "$concat": [
                { "$substr": [
                    { "$subtract": [ "$FileSize", { "$mod": [ "$FileSize", 1 ] }]},
                    0,
                    -1
                ]},
                { "$substr": [ { "$mod": [ "$FileSize", 1 ] }, 1, 3] },
                " MB",
            ]
        }
    }}

または、MongoDB 2.6以降のバージョンでは $project を使用して、または必要に応じて長く使用して、単一の$letに結合します。 1つのパイプラインステージは、2つよりも効率的です。

    { "$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 を使用)、「長さ」引数を残りの文字列にスローして、任意の長さの数を処理できます。 「残り」を$modの使用から分離すると、文字列の長さが小数点以下2桁まで常に「3」になり、先頭の0をスキップするために2番目の位置から始まります。

あなたが要求したものを正確に返します:

{
        "_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"
}
18
Blakes Seven

ステージ2.5を追加:P

{
    $project:{
        FileName:1,
            FileSize:{$substr:["$FileSize", 0, -1 ]}
    }
}

FileSizeは整数であり、それを文字列に変換する操作はありません。したがって、ハックを使用し、substrを使用して文字列に変換できます。0は開始文字列、-1は残りの文字列です。

27
Hiren S.

MongoDB v4.0では、値を文字列に変換する $ toString 演算子を使用できます。

db.col.aggregate([
    {
        $project: {
            FileSize: { $concat: [ { $toString: "$FileSize" }, " MB" ] }
        }
    }
])
2
mickl