【问题标题】:Linq Mongodb Multiple sums as columns with where for eachLinq Mongodb 多个总和作为列,每个列的位置
【发布时间】:2014-03-18 18:06:31
【问题描述】:

我有一个 Mongo Doc 如下

{
    userid: "jd",
    fullname: "john doe",
    Tracker : [
        { 
            type: "aaa",
            total: "111"
            state: "Active"
        }
        { 
            type: "bbb",
            total: "222"
            state: "Active"
        }
        { 
            type: "aaa",
            total: "333"
            state: "Active"
        }
        { 
            type: "ccc",
            total: "111"
            state: "Active"
        }
        {
            type: "ccc",
            total: "111"
            state: "Inactive"
        }
   ]
}

我的目标是在 vb.net(或我可以转换为 vb.net 的 c#)中有一个 linq 查询,它总结了每种类型的所有总数,但在列中,而不是在行中

userid    fullname    aaa    bbb   ccc 
jd        john doe     444   222   111

到目前为止,我得到了: 注意:_users 是我的 mongocollection

dim results = From u in _users.AsQueryable(Of MyClass)() _
Order by _u.fullname
Where _u.Tracker.Any(Function(typestate) typestate.state="Active"
Select _u.userid, _u.fullname, totalAAA = _u.Tracker.Sum(Function(tAAA) tAAA.total),  totalBBB = _u.Tracker.Sum(Function(tBBB) tBBB.total), totalCCC = _u.Tracker.Sum(Function(tCCC) tCCC.total)

我知道totalAAA、totalBBB 和totalCCC 会产生相同的结果,我需要为它们中的每一个设置一个特定的were 子句,只是不知道该怎么做,或者是否有更好的方法

谢谢

【问题讨论】:

    标签: .net vb.net mongodb linq aggregation-framework


    【解决方案1】:

    您所追求的是聚合管道。它不是 LINQ 类型的查询,而是构建为一系列 BSON 文档。见你的documentation.

    管道结构如下:

    db.collection.aggregate([
        // Unwind the array
        { "$unwind": "$Tracker" }
    
        // Match the condition
        { "$match": { "Tracker.state": "active" } },
    
        // Project the output to new fields
        { "$project": {
            "user_id": 1,
            "firstname": 1,
            "aaa": { "$cond": [
                { "$eq": [ "$type", "aaa" ] },
                "$total",
                0
            ]},
            "bbb": { "$cond": [
                { "$eq": [ "$type", "bbb" ] },
                "$total",
                0
            ]}
            "ccc": { "$cond": [
                { "$eq": [ "$type", "ccc" ] },
                "$total",
                0
            ]}
        }},
    
        // Group the total 
        { "$group": {
            "_id": { 
                "user_id": "$user_id",
                "type": "$type",
            },
            "fullname": { "$first": "$fullname" },
            "aaa": { "$sum": "$aaa" },
            "bbb": { "$sum": "$bbb" },
            "ccc": { "$sum": "$ccc" }
        }},
    
        // Final projection to clear up
        { "$project": {
            "_id": 0,
            "user_id": 1
            "fullname": 1,
            "aaa": 1,
            "bbb": 1,
            "ccc": 1
        }}
    ])
    

    因此,这允许您“展开”和“匹配”文档数组中的项目,以便只选择所需的条件。然后通过“$project”对文档进行“重构”,最后“分组”以求总和。

    【讨论】:

    • @user3146613 没问题。很高兴有帮助。感谢您一如既往地接受我的回答:)
    【解决方案2】:

    谢谢尼尔,

    我试图将您的示例改编为我的代码,但由于我需要向其中添加更多“类型”而变得非常冗长;我开始玩我原来的 linq 并让它工作

        dim results = From u in _users.AsQueryable(Of MyClass)() _
    Order by _u.fullname
    Where _u.Tracker.Any(Function(typestate) typestate.state="Active"
    Select _u.userid, _u.fullname, _
     totalAAA = _u.Tracker.Where(Function(tAAA) tAAA.Type="aaa").Sum(Function(tAAA) tAAA.total), _
     totalBBB = _u.Tracker.Where(Function(tBBB) tBBB.Type="bbb").Sum(Function(tBBB) tBBB.total), _
     totalCCC = _u.Tracker.Where(Function(tCCC) tCCC.Type="ccc").Sum(Function(tCCC) tCCC.total)
    

    效果很好而且相当快;使用我的方法有什么问题,因为做事的方法总是不止一种,上面的 linq 会遇到什么盲点吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-15
      • 1970-01-01
      • 1970-01-01
      • 2020-08-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多