2017-02-08 2 views
-1

私はMongo DBに様々なクライアント(以下「組織」といいます)向けの「注文」をいくつか持っています。各注文には、顧客に請求する1件以上の支払い(2月1日〜200日、3月1日〜200日など)が含まれている場合があります。日付と金額を返すためのMongoクエリーを書く方法はありますか?

私は私には3つの値を組織し、リターンで区分すべての受注を通して見るクエリを、書く方法を把握しようとしている:

入力: 機関(モンゴフィールド:destinationId)

出力: - 日充電する(モンゴフィールド:dateCharge) - 額充電する(モンゴフィールド:価格) - 手数料なしデポジット(モンゴフィールズ(数学) - 価格マイナスtotalFee)

やっている場合クエリの数学はあまりにも困難な場合、私は単にtotalFeeフィールドを取得し、Excel/Googleスプレッドシートで数式を計算することができます。ここで

は、私が持っているサンプル文書です:

{ 
    "_id" : ObjectId("588e79e2e7cd645918a27c82"), 
    "userId" : "5840e880b41687d46829ee26", 
    "orderId" : "1001GJ", 
    "updateAt" : ISODate("2017-01-29T23:25:22.566Z"), 
    "createAt" : ISODate("2017-01-29T23:25:22.566Z"), 
    "paymentsPlan" : [ 
     { 
      "_id" : ObjectId("588e79e2e7cd645918a27c7c"), 
      "description" : "Payment 1 of 4", 
      "feeProcessing" : 3.92, 
      "feeCollections" : 5.77, 
      "totalFee" : 9.69, 
      "originalPrice" : 125, 
      "basePrice" : 115.31, 
      "price" : 125, 
      "dateCharge" : ISODate("2017-01-29T23:25:22.092Z"), 
      "destinationId" : "acct_17x0WQEVwZei3oeH", 
      "version" : "v2", 
      "updateAt" : ISODate("2017-01-29T23:30:04.393Z"), 
      "createAt" : ISODate("2017-01-29T23:25:22.520Z"), 
      "paymentMethods" : [ 
       "card", 
       "bank" 
      ], 
      "attempts" : [ 
       { 
        "message" : "done", 
        "status" : "succeeded", 
        "dateAttemp" : ISODate("2017-01-29T23:30:04.387Z"), 
        "_id" : ObjectId("588e7afce7cd645918a27c84") 
       } 
      ], 
      "status" : "succeeded", 
      "wasProcessed" : true, 
      "discountCode" : "", 
      "discount" : 0 
     }, 
     { 
      "_id" : ObjectId("588e79e2e7cd645918a27c7d"), 
      "description" : "Payment 2 of 4", 
      "feeProcessing" : 3.64, 
      "feeCollections" : 5.3, 
      "totalFee" : 8.94, 
      "originalPrice" : 115, 
      "basePrice" : 106.06, 
      "price" : 115, 
      "dateCharge" : ISODate("2017-01-29T23:25:22.092Z"), 
      "destinationId" : "acct_17x0WQEVwZei3oeH", 
      "version" : "v2", 
      "updateAt" : ISODate("2017-01-29T23:35:04.316Z"), 
      "createAt" : ISODate("2017-01-29T23:25:22.524Z"), 
      "paymentMethods" : [ 
       "card", 
       "bank" 
      ], 
      "attempts" : [ 
       { 
        "message" : "done", 
        "status" : "succeeded", 
        "dateAttemp" : ISODate("2017-01-29T23:35:04.310Z"), 
        "_id" : ObjectId("588e7c28e7cd645918a27c86") 
       } 
      ], 
      "status" : "succeeded", 
      "wasProcessed" : true, 
      "discountCode" : "", 
      "discount" : 0 
     }, 
     { 
      "_id" : ObjectId("588e79e2e7cd645918a27c80"), 
      "description" : "Payment 3 of 4", 
      "feeProcessing" : 6.97, 
      "feeCollections" : 10.62, 
      "totalFee" : 17.59, 
      "originalPrice" : 230, 
      "basePrice" : 212.41, 
      "price" : 230, 
      "dateCharge" : ISODate("2017-02-10T16:00:00.000Z"), 
      "destinationId" : "acct_17x0WQEVwZei3oeH", 
      "version" : "v2", 
      "updateAt" : ISODate("2017-02-08T15:57:22.891Z"), 
      "createAt" : ISODate("2017-01-29T23:25:22.528Z"), 
      "paymentMethods" : [ 
       "card", 
       "bank" 
      ], 
      "attempts" : [], 
      "status" : "pending", 
      "wasProcessed" : false, 
      "discountCode" : "", 
      "discount" : 0 
     }, 
     { 
      "_id" : ObjectId("588e79e2e7cd645918a27c81"), 
      "description" : "Payment 4 of 4", 
      "feeProcessing" : 6.97, 
      "feeCollections" : 10.62, 
      "totalFee" : 17.59, 
      "originalPrice" : 230, 
      "basePrice" : 212.41, 
      "price" : 230, 
      "dateCharge" : ISODate("2017-02-24T16:00:00.000Z"), 
      "destinationId" : "acct_17x0WQEVwZei3oeH", 
      "version" : "v2", 
      "updateAt" : ISODate("2017-02-08T15:57:26.081Z"), 
      "createAt" : ISODate("2017-01-29T23:25:22.529Z"), 
      "paymentMethods" : [ 
       "card", 
       "bank" 
      ], 
      "attempts" : [], 
      "status" : "pending", 
      "wasProcessed" : false, 
      "discountCode" : "", 
      "discount" : 0 
     } 
    ], 
    "status" : "active", 
    "description" : "Boys 18U", 
    "__v" : 2 
} 

私は、これは新人の質問です知っているが、私は自分が私のビジネスに資金を提供していますし、私の開発者がしばらく出ていると、クライアントはこのために私に尋ねました情報。どんな助けも素晴らしいだろう。

+0

私はこのクエリを使用して特定の組織からのすべての注文を取得することができます。db.getCollection( '受注')({ 'paymentsPlan.destinationId' が見つかり: "acct_17x0WQEVwZei3oeH "})、その順序でデータを返す方法がわかりません。 – flipdiggity

答えて

0

私は開発者と協力してこの問題を解決しました。それが最も効率的かどうかは分かりませんが、うまくいきます。

var mapFunction1 = function() { 
    for (var idx = 0; idx < this.paymentsPlan.length; idx++) { 
     if (this.paymentsPlan[idx].status === 'pending') { 
      var key = this.paymentsPlan[idx].dateCharge.toISOString().substring(0, 10); 
      var price = this.paymentsPlan[idx].price - this.paymentsPlan[idx].totalFee; 
      emit(key, price); 
     } 

    } 

}; 

var reduceFunction1 = function (dateCharge, price) { 
    return Array.sum(price); 
}; 

db.orders.mapReduce(
    mapFunction1, 
    reduceFunction1, 
    { 
     out: { inline: 1 }, 
     query: { "paymentsPlan.destinationId": "acct_17vBpJHXmwMXUx1q" 
     } 
    } 
) 
0

代替として、以下の集計を使用できます。

$match - このステージは、クエリ条件

$unwindの両方に一致する少なくとも1つの埋め込まれた文書が存在し、すべてのpaymentsPlanの配列を維持する - この段階ではpaymentsPlan配列を分割し、メイン文書をマージします。

$match - この段階では、クエリ基準に一致するドキュメントのみが保持されます。

$groupからdateChargeによってドキュメントとは、各ドキュメントのpricetotalFeeとの間の差をcalcualteし、各グループの差分を合計し、このステージ意志基。

db.orders.aggregate({ 
    $match: { 
     "paymentsPlan": { 
      $elemMatch: { 
       "destinationId": "acct_17x0WQEVwZei3oeH", 
       "status": "pending" 
      } 
     } 
    } 
}, { 
    $unwind: "$paymentsPlan" 
}, { 
    $match: { 
     "paymentsPlan.destinationId": "acct_17x0WQEVwZei3oeH", 
     "paymentsPlan.status": "pending" 
    } 
}, { 
    $group: { 
     _id: { 
      $dateToString: { 
       format: "%Y-%m-%d", 
       date: "$paymentsPlan.dateCharge" 
      } 
     }, 
     "price": { 
      $sum: { 
       $subtract: ["$paymentsPlan.price", "$paymentsPlan.totalFee"] 
      } 
     } 
    } 
}); 

サンプルの応答:

{ "_id" : "2017-02-10", "price" : 212.41 } 
{ "_id" : "2017-02-24", "price" : 212.41 } 
+0

ありがとう@veeram。これはクエリーとしてのmapreduceより効率的ですか? – flipdiggity

+0

私はあなたのニーズに合わせてベンチマークをしたいと思いますが、集約はmap reduceよりもはるかに効率的でなければなりません。 MapのreduceはJavaScriptコードを使用し、JavaScriptエンジンの内部では実行されるので、高レベルの集約はサーバー上でネイティブに実行されます。ここに関連する投稿です。http://stackoverflow.com/questions/13908438/is-mongodb-aggregation-framework-faster-than-map-reduce – Veeram

+0

これは良い投稿でした。私があなたの集計を実行するとき、私はRobomongoから "InternalError:too much recursion"というエラーが出ますが、それはmap reduceと一緒に働きます。 – flipdiggity

関連する問題