说明: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
-----------------------------------------------------------------------------------------
转载与引用请注明出处。
时间仓促,水平有限,如有不当之处,欢迎指正。