2

とドキュメントごとの平均値を計算します。私の質問です:特定のクエリでは、私はすべてのデータを持つすべてのフリーランサーを見つけ、それぞれの平均評価を計算する必要があります。結局、私はフリーランサーの配列を得るだろう。それぞれは、自分の計算した平均レーティングが、新しいフィールド "avg_rating"かそのようなものに格納されていることが望ましい。は、私はそのように定義マングースモデルを持っているソート

私はmongodb集計を調べようとしましたが、正直なところ多くのことを理解していませんでした。

私の説明が十分正確ではない場合は、事前にお詫びと申し訳ありません。これは将来的に他の誰かを助けることができる

Freelancer.aggregate(
    [{ 
      $project: { 
       fname: "$fname", 
       lname: "$lname", 
       rating_avg: { 
        $divide: [{ 
         $reduce: { 
          input: "$ratings.rating", 
          initialValue: 0, 
          in: { 
           $sum: ["$$value", "$$this"] 
          } 
         } 
        }, { 
         $size: "$ratings" 
        }] 
       } 
      } 
     }, 
     { 
      $sort: { 
       rating_avg: -1 
      } 
     } 
    ], 
    function (err, results) { 
     res.send(results); 
    }); 
}); 

希望:

+0

[埋め込みドキュメント/配列内のフィールドの平均を計算する](https://stackoverflow.com/questions/30289071/calculate-the-average-of-fields-in-embedded-documents-array) – Li357

答えて

2

MongoDB 3.2(当然、$projectで修正しています):

Freelancer.aggregate([ 
    { "$addFields": { 
    "rating_avg": { "$avg": "$ratings.rating" } 
    }}, 
    { "$sort": { "rating_avg": -1 } } 
],function(err, results) { 
    res.send(results) 
}) 

また、$reduceが利用可能になるMongoDB 3.4を使用する場合、$projectの代わりに$addFieldsを使用しています。 $projectで修正された場合の2番目の書式は、MongoDB 3.2でも有効です.3番目の書式も同様です。

+0

もう一度ありがとう。後で集約演算子をよりよく把握するためにこれらを実装しようとします。 –

+0

@KyleSentient Learningはうまくいって楽しいです。私はここでレッスンをしたいと思います。「平均的」には「$ avg」と思っています。 '$ reduce'はすべて「あなたがそれを必要とするとき」です。しかし、すでに運営者がいる共通の行動を実行するために、実際にはそれを必要としません。ここでMongoDB 3.2で導入された2つのもの1.) '$ avg'は配列2を受け入れます。'$ ratings.rating'のような配列の単一のプロパティーのような配列式を、それらの値の配列に「短くする」ことができます。 –

1

私のコードをいじりし、いくつかの他のスタックを読んだ後、私は私のニーズのために罰金を作品解決策を見つけました。

Freelancer.aggregate([ 
    { "$addFields": { 
    "rating_avg": { 
     "$reduce": { 
     "input": "$ratings", 
     "initialValue": 0, 
     "in": { 
      "$add": [ 
      "$$value", 
      { "$divide": [ "$$this.rating", { "$size": "$ratings" } ] } 
      ] 
     } 
     } 
    } 
    }}, 
    { "$sort": { "rating_avg": -1 } } 
],function(err, results) { 
    res.send(results) 
}) 

あるいはビット短く$avg$mapを使用して::

Freelancer.aggregate([ 
    { "$addFields": { 
    "rating_avg": { 
     "$avg": { 
     "$map": { 
      "input": "$ratings", 
      "as": "el", 
      "in": "$$el.rating" 
     } 
     } 
    } 
    }}, 
    { "$sort": { "rating_avg": -1 } } 
],function(err, results) { 
    res.send(results) 
}) 

そしてもちろんの最短まだ我々がここでcode golfを再生しようとしている場合は、その式を短縮することができる

+1

の可能な複製これは '$ group'を介した「集約」を必要とせず、単なる「現在の文書」の計算であるため、これは最適なアプローチであることに注意してください。私は構文が実際には '' $ avg'(https://docs.mongodb.com/manual/reference/operator/aggregation/avg/)を['$ map'](https ://docs.mongodb.com/manual/reference/operator/aggregation/map/)このリストの '$ sum'のような' $ avg'は、配列を入力として取ることができるからです。 –

+1

また、 '$ reduce'が使われているので(MongoDB 3.4の機能)、' '$ addFields'(https://docs.mongodb.com/manual/reference/operator/aggregation/addFields/)(別のMongoDB 3.4)を使用し、 "$ fname"と "$ lname"を指定しないでください。ここでも「1」と書かれている可能性があります。 –

+0

@NeilLunn私は参照してください。集約についてはまだ私は初心者です。情報に感謝します。私は時間を得るときに私のコードを最適化しようとします –

関連する問題