.NET MongoDB Driver 2.2使用示例

说明:mongoDBService是对各种常用操作的封装

public class MongoDBService
{
        #region 变量
        /// <summary>
        /// 缓存
        /// </summary>
        private static ConcurrentDictionary<string, Lazy<MongoClient>> m_mongoClientCache = 
            new ConcurrentDictionary<string, Lazy<MongoClient>>();
        /// <summary>
        /// 连接字符串
        /// </summary>
        private string m_connectionStr = string.Empty;
        /// <summary>
        /// 数据库名称
        /// 支持运行时更改
        /// </summary>
        public string DatabaseName { get; set; }
        /// <summary>
        /// 设置GridFS参数
        /// </summary>
        public GridFSBucketOptions BucksOptions { get; set; }
        #endregion

       
        /// <summary>
        /// 初始化操作
        /// </summary>
        public MongoDBService(string connStr, string database)
        {
            m_connectionStr = connStr;
            DatabaseName = database;
        }

        /// <summary>
        /// 获得Mongo客户端
        /// </summary>
        /// <param name="connStr">连接串</param>
        /// <returns></returns>
        private static MongoClient GetClient(string connStr)
        {
            if (string.IsNullOrWhiteSpace(connStr)) throw new ArgumentException("MongoDB Connection String is Empty");

            return m_mongoClientCache.GetOrAdd(connStr,
                new Lazy<MongoClient>(() =>
                {
                    return new MongoClient(connStr);
                })).Value;
        }
        /// <summary>
        /// 插入操作
        /// </summary>
        /// <param name="collectionName">集合名</param>
        /// <param name="t">插入的对象</param>
        /// <returns>返回是否插入成功true or false</returns>
        public bool Insert<T>(string collectionName, T t)
        {
            if (string.IsNullOrWhiteSpace(collectionName)) throw new ArgumentException("collectionName是null、空或由空白字符组成");
            MongoClient client = GetClient(m_connectionStr);
            var db = client.GetDatabase(DatabaseName);
            var collection = db.GetCollection<T>(collectionName);
            Task task = collection.InsertOneAsync(t);
            task.Wait();
            return !task.IsFaulted;
        }

    //其他操作
    ......
}

数据模型

   /// <summary>
    /// 没有子文档的模型
    /// </summary>
    public class Model1
    {
        public string Field1A { set; get; }
        public int Field1B { set; get; }
        public double Field1C { set; get; }
        public float Field1D { set; get; }
        public List<string> Field1E { set; get; }
    }

    /// <summary>
    /// 含有子文档和_id字段
    /// </summary>
    public class Model2
    {
        public string Id { set; get; }
        public string Field2A { set; get; }
        public DateTime Field2B { set; get; }

        public List<Model1> Field2C { set; get; }
    }

一、简单操作

1创建文档

//错误写法1.字符串未加引号
            /* 
             *“System.FormatException”类型的未经处理的异常在 MongoDB.Bson.dll 中发生 
             * 其他信息: Invalid JSON number '1A'.
            */
            string json1Error = @"{'Id': 1AAAA1}";
            //改正
            string json1Right = @"{'Id':'1AAAA1'}";


//错误写法2.集合中的引号嵌套
            /*
             * System.FormatException”类型的未经处理的异常在 MongoDB.Bson.dll 中发生 
             * 其他信息: JSON reader was expecting ':' but found '':''.
             */
            string json2Error = @"{'Field2B': '[
                            {
                                'Field1E':'[]'
                            }
                        ]'}";
//改正
            string json2Right = @"{'Field2B': [
                            {
                                'Field1E':[]
                            }
                        ]}";


 //错误写法3 构造键值对时,“:”使用中文输入法
            /*
             * System.FormatException”类型的未经处理的异常在 MongoDB.Bson.dll 中发生 
             * 其他信息: Invalid JSON input ''.
             */
            string json3Error = @"{'Id':'1AAAA1'}";
//改正
            string json3Right = @"{'Id':'1AAAA1'}";
            #endregion

//将json转换为BsonDocument
            string json = @"{ 'Id':'100000000001',
                  'Field2A':'100',
                  'Field2B':'20160913', 
                  'Field2C':[
                    { 
                         'Field1A':'在MongoDB中一条记录是一个文档',
                         'Field1B':1,
                         'FieldC':13.14, 
                         'Field1D':'13.14F',
                         'Field1E':[]
                    }
                  ]
                }";

            BsonDocument doc1 = BsonDocument.Parse(json3Right);

            
//也可以这样创建
            BsonDocument doc2 = new BsonDocument
            {
                 { "Id", "100000000000" },
                 { "Field2A","100"},
                 { "Field2B",DateTime.Now},
                 { "Field2C", new BsonArray
                    {
                         new BsonDocument("Field1A","MongoDB具有高性能,高可用性,高扩展性"),
                         new BsonDocument("Field1B",1),
                         new BsonDocument("Field1C",0.618),
                         new BsonDocument("Field1D",0.618F),
                         new BsonDocument("Field1E",new BsonArray()),
                    }
                 }
            };

2 插入文档

调用的主要方法IMongoCollection<TDocument>.InsertOneAsync

           Model2 model = new Model2 
            {
                Id = Guid.NewGuid().ToString("N"),
                Field2A = "2",
                Field2B = DateTime.Now.Date,
                Field2C = new List<Model1>()
            };

            for (int i = 0; i < 5; i++)
            {
                Model1 model1 = new Model1 
                {
                    Field1A = "Welcome to the MongoDB",
                    Field1B = i,
                    Field1C = 3.1415926,
                    Field1D = 3.1415926F,
                    Field1E = new List<string>()
                };
                model.Field2C.Add(model1);
            }
            //插入一个collection
            bool t = mongoDBService.Insert(collectionName, model);    

结果:

3删除文档

调用主要方法IMongoCollection<TDocument>.DeleteMany

mongoDBService.Delete<Model2>(collectionName, m => m.Field2A.Equals(DateTime.Parse("2016-09-08")));

二、复杂操作

1插入子文档

调用主要方法IMongoCollection<TDocument>.UpdateMany

        Model1 model1 = new Model1
            {
                Field1A = "MongoDB是一种开源文档型数据库",
                Field1B = 100,
                Field1C = 3.1415926,
                Field1D = 3.1415926F,
                Field1E = new List<string>()
            };

            Model2 model2 = new Model2
            {
                Id = new Guid().ToString("N"),
                Field2A = "1",
                Field2B = DateTime.Now.Date,
                Field2C = new List<Model1>()
            };
        FilterDefinitionBuilder<Model2> filterBuilder = Builders<Model2>.Filter;
            //过滤条件字段Field2A==2
            FilterDefinition<Model2> filter = filterBuilder.Eq(doc => doc.Field2A, "1");
            SortDefinitionBuilder<Model1> sortBuilder = Builders<Model1>.Sort;
            //按字段Field1A升序排列
            SortDefinition<Model1> sort = sortBuilder.Ascending(pu => pu.Field1A);
            //最新插入的在最前面,这是通过将PushEach方法的参数position设置为0实现的
            UpdateDefinitionBuilder<Model2> updateBuilder = Builders<Model2>.Update;
            UpdateDefinition<Model2> update = updateBuilder.PushEach(doc => doc.Field2C, new List<Model1> { model1 }, null, 0, sort);
            UpdateResult updateResult = mongoDBService.DocumentUpdate(collectionName, filter, update);

执行结果:

2更新子文档

调用主要方法IMongoCollection<TDocument>.UpdateMany

        string commentContent = "通过Update修改了";
            FilterDefinitionBuilder<Model2> filterBuilder = Builders<Model2>.Filter;
            //找到父文档,过滤条件为Field2A=2并且Field2B=“2018-01-21T16:00:00.000Z”
            FilterDefinition<Model2> filterFather = filterBuilder.Eq(doc => doc.Field2A, "1")
                & filterBuilder.Eq(doc => doc.Field2B, DateTime.Parse("2016/9/13 0:00:00"));
            //找到子文档,过滤条件Field1B=1,条件作用与字段Field2C,他是个集合,用来存储子文档
            FilterDefinition<Model2> childFilter = filterBuilder.ElemMatch(
                listField => listField.Field2C, childfield => childfield.Field1B == 100);
            //上述条件的并
            FilterDefinition<Model2> filter = Builders<Model2>.Filter.And(new FilterDefinition<Model2>[] { filterFather, childFilter });

            //使用XXXX.$.XXXX定位字段
            var update = Builders<Model2>.Update.Set("Field2C.$.Field1A", commentContent);

            UpdateResult updateResult = mongoDBService.DocumentUpdate(collectionName, filter, update);

运行结果:

3 找到某一个子文档

调用主要方法IMongoCollection<TDocument>.Find,将调用结果转化为List<T>,然后取第一个元素。

       FilterDefinitionBuilder<Model2> filterBuilder = Builders<Model2>.Filter;
            //找到父文档,过滤条件为Field2A=2并且Field2B=“2018-01-21T16:00:00.000Z”
            FilterDefinition<Model2> filterFather = filterBuilder.Eq(doc => doc.Field2A, "2")
                & filterBuilder.Eq(doc => doc.Field2B, DateTime.Parse("2018-01-21T16:00:00.000Z"));
              

            //投影定义创建器:ProjectionDefinitionBuilder
            //用ProjectionDefinition过滤子文档,投影器创建器作用于Field2C,他是一个集合,用来保存多个子文档;过滤条件为Field1C = 3.1415926
            ProjectionDefinitionBuilder<Model2> projBuilder = Builders<Model2>.Projection;
            ProjectionDefinition<Model2> proj = projBuilder.ElemMatch(listField => listField.Field2C, childfield => childfield.Field1C == 3.1415926);

            FindOptions options = new FindOptions() { AllowPartialResults = true };
            Model2 info = mongoDBService.Single<Model2>(collectionName, filterFather, options, proj);

结果:

4 获得所有子文档

调用主要方法IMongoCollection<TDocument>.Find

        //投影定义创建器:ProjectionDefinitionBuilder
            //用ProjectionDefinition过滤子文档
            ProjectionDefinitionBuilder<Model2> projBuilder = Builders<Model2>.Projection;
            ProjectionDefinition<Model2> proj = projBuilder.ElemMatch(listField => listField.Field2C, childfield => childfield.Field1B ==0);

            List<Model2> info = mongoDBService.List<Model2>(collectionName,
                m => m.Field2A == "2" && m.Field2B == DateTime.Parse("2018-01-21T16:00:00.000Z"), proj);

5文档排序

调用主要方法IMongoCollection<TDocument>.Find

       SortDefinitionBuilder<Model2> sortBuilder = Builders<Model2>.Sort;
            ////按字段Field2A降序排列
            SortDefinition<Model2> sort = sortBuilder.Descending(m => m.Field2A);

            List<Model2> info = mongoDBService.FindAllList(collectionName, sort);

6内嵌文档分页

调用主要方法IMongoCollection<TDocument>.Find

若匹配出多个文档,取第一个元素

       //投影定义创建器:ProjectionDefinitionBuilder
            //用ProjectionDefinition过滤子文档
            ProjectionDefinitionBuilder<Model2> projBuilder = Builders<Model2>.Projection;
            //Include :确定要包含哪些字段值(即给哪些字段赋值)
            //Slice:获得子文档集合分片,第一个参数field指取出的子文档集合,第二各参数skip指跳过多少个子文档,第三个参数limit取出多少个
            ProjectionDefinition<Model2> proj = projBuilder.Include(m => m.Field2C).Slice(m => m.Field2C, 1, 3);
            //过滤条件是Field2A=2
            Model2 doc = mongoDBService.SubdocumentPageList<Model2>(collectionName, m => m.Field2A == "2", proj);

7删除子文档

调用主要方法IMongoCollection<TDocument>.UpdateOne

       //过滤器作用与Field2C字段,过滤条件是Field1B = 1
            var update = Builders<Model2>.Update.PullFilter(m => m.Field2C, (y => y.Field1B == 2));
            //父文档过滤条件为Field2A=2,如果匹配出多个父文档,只操作第一个文档
            mongoDBService.UpdateOne<Model2>(collectionName, m => m.Field2A == "2", update);

8聚集操作

调用主要方法IMongoCollection<TDocument>.Aggregate

1)筛选数据

        //unwind阶段
            var unwind = new BsonDocument{
                     {
                       "$unwind","$Field2C"
                     }
                  };
            //match阶段。匹配条件Field2A=2,Field1B=1
            //注意Field2A为字符串类型,2用引号包起来;而Field1B为整形,所以1不能用引号包起来
            var match = new BsonDocument
                {
                    {
                        "$match",
                        new BsonDocument
                        {
                            {
                                "Field2A","2"                             
                            }
                            ,
                             {
                                "Field2C.Field1B",1                         
                            }
                        }
                    }
                };
            //group阶段
            var group = new BsonDocument
                {
                    {
                        "$group",
                        new BsonDocument
                        {
                            {
                                "_id","$Field1C"
                            },
                            {
                              "Field2C",
                               new BsonDocument
                              {
                                 {
                                   "$push","$Field2C"
                                 }
                             }
                        }
                        }                     
                        
                    }
                };
            var r = mongoDBService.Aggregate<Model2>(collectionName, new BsonDocument[] { unwind, match, group });

      //也可以使用
      var r = mongoDBService.Aggregate(collectionName, unwind, match, group);

2)获得数组大小

      var match = new BsonDocument
            {
                {
                    "$match",new BsonDocument{{"Field2A","2"}}
                }
            };

            var project = new BsonDocument
            {
                {
                    "$project",new BsonDocument
                    {
                        {
                            "NumofArray",
                            new BsonDocument
                            {
                                { "$size", "$Field2C" }
                            }
                        }
                    }
                }
                
            };
            BsonDocument bson = mongoDBService.Aggregate<BsonDocument>(collectionName, 
                new BsonDocument[] { match, project }).FirstOrDefault<BsonDocument>();
            int count = bson != null?bson.GetValue("NumofArray").AsInt32:0;

 MongoDBService下载地址:https://files.cnblogs.com/files/hdwgxz/MongoDBService.rar

-----------------------------------------------------------------------------------------

时间仓促,水平有限,如有不当之处,欢迎指正。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏数据和云

Oracle性能优化-子查询到特殊问题

编辑手记:前面我们介绍常用的子查询优化方法,但总有一些情况时在规律之外。谨慎处理方能不掉坑。 前文回顾: 性能优化之查询转换 - 子查询类 将SQL优化做到极...

3007
来自专栏技术博客

C#简单的面试题目(五)

61.数组有没有length()这个方法? String有没有length()这个方法?

793
来自专栏技术栈大杂烩

Python源码理解: '+=' 和 'xx = xx + xx'的区别

为什么上面不同的对象执行同一个+会有不同的效果呢? 这就涉及到+的重载, 然而这不是本文要讨论的重点, 上面的只是前菜而已~~~

391
来自专栏aCloudDeveloper

总结:常用的通用数据处理指令

作者:bakari  时间:2012.4.21 1、 操作数类型 Imm立即操作数 Reg寄存器操作数 Mem内存操作数 2、 操作数寻址方式 立即数寻址 寄存...

1828
来自专栏我杨某人的青春满是悔恨

深入理解 weak-strong dance

这时handler持有 Block 对象,而 Block 对象虽然捕获了weakSelf,延长了weakSelf这个局部变量的生命周期,但weakSelf是附有...

544
来自专栏技术博客

C#泛型委托Predicate、Action、Func

Predicate泛型委托:表示定义一组条件并确定指定对象是否符合这些条件的方法。此委托由 Array 和 List 类的几种方法使用,用于在集合中搜索元素。 ...

712
来自专栏专注 Java 基础分享

漫谈计算机编码

我们知道,在计算机内部,所有的信息都是以二进制形式进行存储。无论是字符,或是视频音频文件,最终都会对应到一串由 0 和 1 构成的数字串。所以从我们能看懂的人类...

3566
来自专栏从流域到海域

二叉树的性质和常用操作代码集合

二叉树的性质和常用操作代码集合 性质: 二叉树的性质和常用代码操作集合 性质1:在二叉树的第i层上至多有2^i-1个结点 性质2:...

1949
来自专栏Jackson0714

基础很重要~~04.表表达式-上篇

31512
来自专栏杨建荣的学习笔记

一条SQL语句的执行计划变化探究(r10笔记第9天)

继续上次分析的一个问题,一个简单的SQL语句执行计划有些奇怪,明明可以走唯一性索引但是却走了另外一个索引。 当然了,最后逐步定位,发现是在直方图...

2583

扫码关注云+社区