3

DBRef 経由で保存されたデータを集計することはできますか?

モンゴ2.6

次のようなトランザクション データがあるとします。

{
  _id : ObjectId(...),
  user : DBRef("user", ObjectId(...)),
  product : DBRef("product", ObjectId(...)),
  source : DBRef("website", ObjectId(...)),
  quantity : 3,
  price : 40.95,
  total_price : 122.85,
  sold_at : ISODate("2015-07-08T09:09:40.262-0700")
}

秘訣は、「ソース」は本質的にポリモーフィックであることです。「webpage」、「call_center」など、異なる ObjectId を持つ異なる $ref 値である可能性があります。たとえば、DBRef("webpage", ObjectId("1")) と DBRef("webpage",ObjectId("2")) は、トランザクションが発生した 2 つの異なる Web ページになります。

最終的に、ある期間 (1 か月など) にわたってソース別に集計したいと思います。

db.coll.aggregate( { $match : { sold_at : { $gte : start, $lt : end } } },
                   { $project : { source : 1, total_price : 1 } },
                   { $group : { 
                         _id : { "source.$ref" : "$source.$ref" },
                         count : { $sum : $total_price }
                      } } );

トリックは、$ で始まる変数を使用しようとすると、パス エラーが発生することです。変数でグループ化しようとするか、プロジェクトを介して式を使用して変換しようとします。

これを行う方法はありますか?実際には、集計を介してこのデータをサブコレクションにプッシュして、そこで操作しようとしています。集計できるようにデータを変換するために、何百万ものレコードに対する大規模なカーソル操作を回避しようとしています。

4

2 に答える 2

1

DBRef集計フレームワークでは値を使用できません。代わりに、mapReduceの JavaScript 処理を使用して、使用するプロパティの命名にアクセスする必要があります。

db.coll.mapReduce(
    function() {
        emit( this.source.$ref, this["total_price"] )
    },
    function(key,values) {
        return Array.sum( values );
    },
    {
        "query": { "sold_at": { "$gte": start, "$lt": end } },
        "out": { "inline": 1 }
    }
)

あなたは本当にまったく使ってはいけませんDBRef。使用法は現在基本的に非推奨であり、外部参照が必要だと思われる場合は、独自のコードでこれを「手動で参照」するか、他のライブラリで実装する必要があります。これを使用すると、よりサポートされた方法で実行できます。

于 2015-07-09T00:03:41.063 に答える