2016-11-09 14 views
1

dbsampleから:MongoDBのGET平均各arrayelement

var doc1= new BsonDocument 
{ 
    { "line", "a" }, 
    { "size", new BsonArray { 2 } } 
}; 
var doc2= new BsonDocument 
{ 
    { "line", "xx" }, 
    { "size", new BsonArray { 5, 3, 8} } 
}; 
var doc3= new BsonDocument 
{ 
    { "line", "xx" }, 
    { "size", new BsonArray { 1, 10, 8} } 
}; 

私はグループに線でBsonDocumentをしたい、各ラインの数とすべてのBsonArrayElementの平均を取得します。グループ化とカウントは機能しますが、すべてのBsonArrayElementの平均を取得するにはどうすればよいですか? BsonArrayの長さは、異なる行の間で異なります。

var filterBuilder = Builders<BsonDocument>.Filter; 
var aggregate = collection.Aggregate().Group(new BsonDocument { { "_id", "$line" }, { "count", new BsonDocument("$sum", 1) } }); 
foreach (var document in aggregate.ToEnumerable()) 
{ 
    Console.WriteLine(document); 
} 

私が欲しいの出力:

{ "_id" : "xx", "count" : 2, "avg" : [3, 6.5, 8] } 
{ "_id" : "a", "count" : 1, "avg" : [2]} 

答えて

0

望ましい結果を得るためには、次の演算子を持つ集約パイプラインを構築して実行する必要があるでしょう:

db.collection.aggregate([ 
    { 
     "$group": { 
      "_id": "$line", 
      "count": { "$sum": 1 }, 
      "doc": { "$push": "$$ROOT" } 
     } 
    }, 
    { "$unwind": "$doc" }, 
    { 
     "$unwind": { 
      "path": "$doc.size", 
      "includeArrayIndex": "arrayIndex" 
     } 
    }, 
    { 
     "$group": { 
      "_id": { 
       "line": "$doc.line", 
       "idx": "$arrayIndex" 
      }, 
      "avg": { "$avg": "$doc.size" }, 
      "count": { "$first": "$count" }    
     } 
    }, 
    { "$sort": { "_id.idx": 1 } }, 
    { 
     "$group": { 
      "_id": "$_id.line", 
      "count": { "$first": "$count" }, 
      "avg": { "$push": "$avg" } 
     } 
    }  
]) 

C#実装(未テスト):

var result = await collection.Aggregate() 
    .Group(new BsonDocument { 
     { "_id", "$line" }, 
     { "count", new BsonDocument("$sum", 1) }, 
     { "doc", new BsonDocument("$push", "$$ROOT") }  
    }) 
    .Unwind(x => x.doc) 
    .Unwind(new BsonDocument { 
     { "path", "$doc.size" }, 
     { "includeArrayIndex", "arrayIndex" } 
    }) 
    .Group(new BsonDocument { 
     { "_id", new BsonDocument { 
      { "line", "$doc.line" }, 
      { "idx", "$arrayIndex" } 
     } }, 
     { "avg", new BsonDocument("$avg", "$doc.size") }, 
     { "count", new BsonDocument("$first", "$count") }  
    }) 
    .Sort(new BsonDocument("_id.idx", 1)) 
    .Group(new BsonDocument { 
     { "_id", "$_id.line" }, 
     { "count", new BsonDocument("$first", "$count") }, 
     { "avg", new BsonDocument("$push", "$avg") }, 
    }) 
    .ToListAsync(); 
+0

ありがとうございます。コードはシェルで動作しますが、C#でエラーが発生します。 "'BsonDocument'には 'doc'の定義が含まれておらず、拡張メソッド 'doc'は 'BsonDocument'型の最初の引数を受け入れることができませんでした。 ) " – seeberg

+0

私が答えで述べたように、私はこれをテストしていません。私がチャンスを得るとき、私はリファクタリングを必要とするかもしれないこのステップ '.Unwind(x => x.doc)'で特にパイプラインをデバッグする必要があるかもしれません。 – chridam

+0

私はそれを働かせることができません:( – seeberg