.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 条评论
登录 后参与评论

相关文章

来自专栏深度学习之tensorflow实战篇

python pandas.read_csv参数整理,读取txt,csv文件

pandas.read_csv参数整理 读取CSV(逗号分割)文件到DataFrame 也支持文件的部分导入和选择迭代 更多帮助参见:http://pandas...

6926
来自专栏Google Dart

Dart语言指南(二) 顶

Dart是一种面向对象的语言 包含类和基于 mixin 的继承两部分。每个对象是一个类的实例, 并且 Object.是所有类的父类。 基于 mixin 的继承指...

351
来自专栏光变

你所不知道的Java之Integer

以下内容为作者辛苦原创,版权归作者所有,如转载演绎请在“光变”微信公众号留言申请,转载文章请在开始处显著标明出处。

1160
来自专栏程序员互动联盟

【专业技术】hash_map使用(二)

上次说完了简单类型的hash_map使用,现在说说用户自定义类型:比如对象类型,结构体的hash_map使用。 这种情况比价复杂,我们先...

26911
来自专栏软件开发

JavaSE学习总结(五)——封装,继承,多态很简单

java面向对象的三大特性是:封装、继承与多态,是面向对象编程的核心。 一、封装 简单说封装就是将同一类事物的特性与功能包装在一起,对外暴露调用的接口。 封装:...

2006
来自专栏杨潼的专栏

编写高质量的 JavaScript 代码(一)

针对JavaScript中一些容易被忽略的知识以及一些代码优化方法做了简单的总结,也是《Effective JavaScript》的读书笔记。希望对新手学习有所...

1.8K0
来自专栏非著名程序员

Java 反射基础(下)

? 投稿作者:芮成兵/csdn 原文链接: http://blog.csdn.net/My_TrueLove/article/details/51306921...

1956
来自专栏Java 技术分享

Struts2 转换器

972
来自专栏LeoXu的博客

NDK学习笔记(二)使用JNI同原生代码通信 原

任何使用JNI的操作都需要两次或者三次函数调用,因此要实现大量的原生方法并让它们同Java类保持同步很容易编程一件非常艰辛的工作。

723
来自专栏技术博客

编写高质量代码改善C#程序的157个建议[匿名类型、Lambda、延迟求值和主动求值]

  从.NET3.0开始,C#开始一直支持一个新特性:匿名类型。匿名类型由var、赋值运算符和一个非空初始值(或以new开头的初始化项)组成。匿名类型有如下基本...

844

扫描关注云+社区