从2个字段按顺序对数据排序并按降序排序

时间:2014-09-01 09:58:24

标签: c# mongodb mongodb-.net-driver mongodb-query aggregation-framework

我在MongoDB

中有一个关于此文档的集合
string _id;
string item;
string category;
int mobileView;
int webView;

我想把10个项目按mobileViewwebView的总和降序排序,无论如何我只能通过查询直接实现这一点,或者我应该获取所有数据并循环通过这一切并手动总结mobileViewwebView,然后才获得总数最高的10个?

我一直在阅读有关Aggregation Framework的内容,但据我所知,Sum只有一个字段已被查询分组。我理解的是错误的,如果是这样,如何使用Aggregation Framework

(我不希望Sum的{​​{1}}总View按相同的category分组,我只需Sum View {{1}} 1}}在每个项目上排序之前)

2 个答案:

答案 0 :(得分:3)

聚合框架就是您想要的。不仅仅是为了#34;聚合"但是对于"操纵"文件也是如此。因此,基本上您希望$add运算符和$sort管道获得所需的结果。

我会花一些时间启动一个Visual Studio,所以这里的shell表单不难翻译:

db.collection.aggregate([
    { "$project": {
        "item": 1,
        "category": 1,
        "mobileView": 1,
        "webView": 1,
        "totalView": { "$add": [ "$mobileView", "$webView" ] }
    }},
    { "$sort": { "totalView": -1 } }
])

所以基本上"计算"一个字段,然后使用"投影"结果为$sort上的字段。

只是BSON文件,所以不应该很难。

特别是对于C#语法,请执行以下操作:

var project = new BsonDocument {
    {
        "$project",
        new BsonDocument()
            .Add( "item", 1 )
            .Add( "category", 1 )
            .Add( "mobileView", 1 )
            .Add( 
                "totalView",
                new BsonDocument()
                    .Add( "$add", new BsonArray {
                        "$mobileView", "$webView"
                    })
            )
    } 
};

var sort = new BsonDocument {
    {
        "$sort",
        new BsonDocument {
            { "totalView", -1 }
        }
    }
};

var pipeline = new[] { project, sort };
var results = collection.Aggregate(pipeline);

所有 $project 项目与 $group 一样明确""要包含在舞台输出中的命名字段。在聚合框架中,您想要的字段是"全部或全部"并且您必须指定您希望在下一个管道阶段或管道末端可见的每个管道。就管道而言,未提及的字段不再存在。

认为unix风格"管道" |你在哪里"链"一个命令对另一个命令的结果,这清楚地类比了这里发生的事情。

答案 1 :(得分:0)

我实际上编写了一个Linq提供程序MongoLinqPlusPlus来生成简单的聚合框架管道,例如你的。

因此,使用MongoLinqPlusPlus,您的查询将变为:

collection.QueryablePlusPlus()
          .Select(c => new {
              OriginalDoc = c,
              SortKey = c.mobileView + c.webView
          })
          .OrderByDescending(c => c.SortKey)
          .Take(10)
          .Select(c => c.OriginalDoc)

(*如果我们可以在排序中进行算术(.OrderByDescending(c => c.mobileView + c.webView)会很好,但聚合框架不直接支持这个。所以我选择要求开发人员显式创建投影,而不是由Linq提供者隐式创建。)