2017-12-30 47 views
0

私はショッピングカートを開発していますが、私の現在の要件はショップオーナーにダッシュボードを表示することです。商品名に重複がある可能性があるため、商品IDで注文商品をグループ化し、合計注文数を持つように合計を実行しました。今私も読める名前が必要ですが、そうすることはエラーを発生させます。mongoDB/mongoose集約パイプラインを使用してカスタムフィールドに基づいて集計値を設定するにはどうすればよいですか?

クエリ

ShoppingCart 
    .aggregate({ $match: { "orderedProducts.registrationDetails.createdByID": LOGGED_IN_ADMIS_ID } }) 
    .project("orderedProducts.productID orderedProducts.title orderedProducts.qty -_id") 
    .unwind("orderedProducts") 
    .group({ _id: "$orderedProducts.productID", counts: { $sum: "$orderedProducts.qty" }, title: "$orderedProducts.title" }) 
    .exec((err, docs) => { 
     if (err) { 
      return res.status(503).send(err); 
     } 
     res.send(docs); 
    }); 

エラーメッセージ:

{ "名": "MongoError"、 "メッセージ":「、 "フィールド 'タイトルは' アキュムレータオブジェクトでなければなりません" OK ":0、" ERRMSG ":" フィールド 'タイトル' アキュムレータオブジェクト」、 "コードでなければなりません":40234、 "コードネーム": "Location40234"}

は、これがどの部分でありますエラーの原因ですタイトル: "$ orderedProducts.title"

答えて

1

私はこの問題があなたのgroupオペレータにあると考えています。具体的には、title: "$orderedProducts.title"を実行しているため、グループ化に問題が発生している可能性があります。 MongoDBはおそらくこのケースをどのように扱うべきか理解していないでしょう。なぜなら、使用する文書のタイトルを優先順位付けする方法がないからです。これが、ある形式のアキュムレータが期待される理由である。 qtyフィールドで使用している$sum

代わりに、グルーピングのtitle部分を省略し、代わりに化合物_idを使用してみてください:

ShoppingCart 
    .aggregate({ $match: { "orderedProducts.registrationDetails.createdByID": LOGGED_IN_ADMIS_ID } }) 
    .project("orderedProducts.productID orderedProducts.title orderedProducts.qty -_id") 
    .unwind("orderedProducts") 
    .group({ _id: { productId: "$orderedProducts.productID", title: "$orderedProducts.title" }, counts: { $sum: "$orderedProducts.qty" } }) 
    .exec((err, docs) => { 
     if (err) { 
      return res.status(503).send(err); 
     } 
     res.send(docs); 
    }); 

警告この溶液には、各productIDために一つのタイトルのみがあると仮定することです。これはproductIDtitleの両方でグループ化されるため、同じproductIDのタイトルが異なると、このソリューションは失敗します。これはあなたのための問題であり、あなたの代わりに与えられたproductIDための全ての製品のタイトルをつかむしたい場合は、次の操作を行うことができます:

ShoppingCart 
    .aggregate({ $match: { "orderedProducts.registrationDetails.createdByID": LOGGED_IN_ADMIS_ID } }) 
    .project("orderedProducts.productID orderedProducts.title orderedProducts.qty -_id") 
    .unwind("orderedProducts") 
    .group({ _id: "$orderedProducts.productID", counts: { $sum: "$orderedProducts.qty" }, titles: { $addToSet: "$orderedProducts.title" } }) 
    .exec((err, docs) => { 
     if (err) { 
      return res.status(503).send(err); 
     } 
     res.send(docs); 
    }); 
0

いずれかの最初のグループのパイプラインで$最後または$を使用し

.group({ 
    _id: "$orderedProducts.productID", 
    counts: { $sum: "$orderedProducts.qty" }, 
    title: { $first:"$orderedProducts.title"} 
}) 

または、

.group({ 
    _id: "$orderedProducts.productID", 
    counts: { $sum: "$orderedProducts.qty" }, 
    title: { $last:"$orderedProducts.title"} 
}) 

あなたが製品をグループ化しているので、タイトルが類似したproduct_idに対してままにしてください。したがって、最後のグループ化されたオブジェクトに添付される最初または最後のものを選択できます。

+0

親愛なる@imixtronご意見ありがとうございます。問題は、私の場合、製品の名前がユニークではないということです。ユーザーが全く同じ名前の2つ以上の異なる製品を作成する可能性があるため、名前の代わりに製品IDで製品をグループ化していたのはこのためです。 – Taha

+0

私のクエリは** _ id **に基づくグループ化と同じです。グループ化されたすべてのドキュメントには同じものがあります。したがって、最初か最後かを選択することができます。 – imixtron

+0

申し訳ありませんが、私は間違っていた、訂正のおかげで。 – Taha

関連する問題