2015-11-24 13 views
10

私のコレクション内のすべてのファイルのサイズが50MB以上の場合、FileNameとFileSizeを投影しようとしていますが、タイプがInt型であるためFileSize型を連結できませんMongodb concat 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」フィールドをどのように連結しますか?

答えて

8

ここでのトリックは小数点精度を処理するために、文字列への変換、およびいくつかのささやかな贅沢を行うために$substrを使用することです:、

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

いっそ、単一$projectに結合しますMongoDB 2.6より後のバージョンでは$letの助けを借りて、または必要に応じて長い間、単一のパイプラインステージは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"であり、先頭の文字をスキップするために2番目の位置から始まります。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" 
} 
:あなたは尋ねた、まさに

戻り値

14

は、ステージ2.5の追加:P

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

ファイルサイズは整数と文字列に変換するために何も操作しません。だからあなたはハックを使うことができ、substrを使って文字列に変換することができます。文字列の先頭と-1は残りの文字列です。

関連する問題