MongoDB从每个arrayelement获得avg

时间:2016-11-09 08:51:55

标签: mongodb mongodb-query aggregation-framework

dbsample:

INSERT INTO tbl2 (year, IDa, field3)
SELECT c.Year,
       c.Ida,
       a.field3
  FROM tbl2 a
       INNER JOIN tbl1 b
               ON a.IDa = b.Ida
       INNER JOIN tbl1 c
               ON field2 = field2
              AND c.year = 2016
 WHERE a.year = '2015';

我想按行对BsonDocument进行分组,得到每行的计数和每个BsonArrayElement的平均值。分组和计数工作,但我如何获得每个BsonArrayElement的平均值? BsonArray的长度在不同的行之间有所不同。

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} }
};

我想要的输出:

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);
}

1 个答案:

答案 0 :(得分: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();