zoukankan      html  css  js  c++  java
  • MongoDB学习笔记~关于官方驱动集成IQueryable之后的一些事

    回到目录

    关于官方驱动集成IQueryable之后的一些事,有好事也有坏事,好事就是它会将你的linq语句非常友好的翻译成MongoDB语句,而坏事就是有一些linq语句不会被翻译,不会被翻译的代价就是将整个结果集装到内存,然后进行linq to object的查询,效率自然是非常低的,呵呵。

    好事

    最新官方驱动中,添加了对IQueryable扩展方法的支持

            public static IMongoQueryable<TDocument> AsQueryable<TDocument>(this IMongoCollection<TDocument> collection);

    1 它对Where完成支持

    _webManageUsersRepository.GetModel().Where(i => i.LoginName == "zzl");

    2 它对group完全支持

     var g = _webManageUsersRepository.GetModel()
                    .GroupBy(i => i.DepartmentID, (i, v) => new 
                    {
                        dept = i,
                        userCount = v.Count()
                    });

    通过断点我们可以看到它所生成的mongodb语句,然后可以把语句放在命令行中去执行看看具体效果

    db.WebManageUsers.aggregate([{ "$group" : { "_id" : "$DepartmentID", "userCount" : { "$sum" : 1 } } }])

    上面写法是我比较喜欢的lambda表达式的方法,语法简介,漂亮,而我不太喜欢linq写法,但是,如果是多字段的分组,你就必须使用linq标准写法了,因为到目前为止,mongo官方驱动还不支持多字段分组的lambda写法,如下面的代码,分组结果就是错误的

     var bb = _webManageUsersRepository.GetModel()
                    .GroupBy(
                    i => new
                    {
                        i.DepartmentID,
                        i.Status
                    },
                    (i, v) => new
                    {
                        dept = i.DepartmentID,
                        status = i.Status,
                        userCount = v.Count()
                    });

    它不能正确的翻译成Mongo表达式

    {aggregate([{ "$group" : { "dept" : "$DepartmentID", "status" : "$Status", "userCount" : { "$sum" : 1 }, "_id" : 0 } }])}

    而使用传统的linq写法就可以被mongo驱动很好的翻译

      var gg = from a in _webManageUsersRepository.GetModel()
                         group a by new
                         {
                             dept = a.DepartmentID,
                             status = a.Status
                         } into g
                         select new RoleCount
                         {
                             dept = g.Key.dept,
                             status = g.Key.status,
                             userCount = g.Count()
                         };

    下面生成的代码是正确的

    aggregate([{ "$group" : { "_id" : { "dept" : "$DepartmentID", "status" : "$Status" }, "__agg0" : { "$sum" : 1 } } }, { "$project" : { "dept" : "$_id.dept", "status" : "$_id.status", "userCount" : "$__agg0", "_id" : 0 } }])}

    可以在mongo客户端上看到正确的结果

    坏事

    对count()方法完成不支持,不推荐使用,如果要用到count(),建议使用mongo原生态的,而不是linq的

                Stopwatch sw1 = new Stopwatch();
                sw1.Restart();
                var a1 = _webManageUsersRepository.Count(i => true);//性能好
                sw1.Stop();
                var at1 = sw1.ElapsedMilliseconds;
    
                Stopwatch sw = new Stopwatch();
                sw.Restart();
                var a = _webManageUsersRepository.GetModel().Count();//性能差
                sw.Stop();
                var at = sw.ElapsedMilliseconds;

    回到目录

  • 相关阅读:
    iSCSI又称为IPSAN
    文档类型定义DTD
    HDU 2971 Tower
    HDU 1588 Gauss Fibonacci
    URAL 1005 Stone Pile
    URAL 1003 Parity
    URAL 1002 Phone Numbers
    URAL 1007 Code Words
    HDU 3306 Another kind of Fibonacci
    FZU 1683 纪念SlingShot
  • 原文地址:https://www.cnblogs.com/lori/p/4483890.html
Copyright © 2011-2022 走看看