1.1.驱动安装
使用NuGet包管理器安装MongoDB C#驱动:MongoDB.Driver
1.2. C#连接MongoDB
//获取MongoDB连接客户端 MongoClient client = new MongoClient("mongodb://root:root@localhost:27017"); //获取数据库 var database = client.GetDatabase("mongtestdb"); //获取集合 var collection = database.GetCollection<Organizations>("Organizations"); 在获取集合时,有两种方式 1.指定集合类型,入上面的方式,指定获取集合时使用指定的类Organizations,优势是可以使用lamda表达式获取属性,查询时不需要转换类型 2.使用BsonDocument获取集合,查询结果若使用类接收,需要转换类型:C#中使用MongoDB聚合管道时必须使用BsonDocument的方式获取集合(目前是) var collection = database.GetCollection<BsonDocument>("Organizations");
2.简单文档结构
以组织表为例,表结构如下图所示
//组织表结构 //Organizations { "_id": ObjectId("60f7961699515da94c20296c"), "CreationTime": ISODate("2015-12-11T10:35:25.000Z"), "CreatorUserId": NumberLong("date 1"), "LastModificationTime": ISODate("2021-07-22T18:54:46.803Z"), "LastModifierUserId": NumberLong("11949267"), "IsDeleted": false, "DeletionTime": null, "DeleterUserId": null, "CreatorUserName": null, "LastModifierUserName": null, "DeleterUserName": null, "OrgId": NumberInt("2"), //组织Id "Name": "某某集团", //组织名称 "ShortName": "某某集团", //组织简称 "Code": "HQW", //组织编码 "Type": NumberInt("100"), //组织类型:公司、部门 "HeadUserId": NumberLong("11944818"), "Sort": NumberInt("1"), "ParentId": NumberInt("0"), //上级组织Id "IsActive": true, //是否启用 "OrganizationLevel": NumberInt("1"), "Leaders":[{ "UserId":"abc", "IsMain":true }] }
2.1.查询
MongoDB脚本
注意:字段可以不用双引号包裹,也可以使用双引号包裹,均可。但是当字段名不符合标识符要求时,一定要使用双引号包裹,否则会报错
//1.查询全部 db.Organizations.find({}) //2.通过Id查询 db.Organizations.find({"_id":ObjectId("60cac0979b3c533a5d1a06e1")}) //3.模糊查询 db.Organizations.find({"ShortName":/互联科技/}) //全模糊 db.Organizations.find({"ShortName":/^互联科技/}) //以“联科技公司”为前缀 db.Organizations.find({"ShortName":/联科技公司$/}) //以“联科技公司”为后缀 //4.in查询 db.Organizations.find({"ShortName":{$in:["电影视效中心","电影特效制作中心"]}}) //5.and查询 db.Organizations.find({"ShortName":"互联科技","Name":"互联科技科技有限公司"}) //6.or查询 db.Organizations.find({$or:[{"ShortName":"电影视效中心"},{"ShortName":"电影特效制作中心"}]}) //7.混合查询 //类似sql: Type=100 and OrgId>=2 and (Name like '%互联%' or ShortName='智能公司') and Code in ('SZN','SHL') db.Organizations.find({ "Type": NumberInt(100), "OrgId": { $gte: 2 }, $or: [{ "Name": /互联/ }, { "ShortName": "智能公司" }], "Code": { $in: ["SZN", "SHL"] } }) C#语法 var filterBuilder = Builders<Organizations>.Filter; //创建过滤条件构建器 { //1.查询全部 var filter = filterBuilder.Empty; //查询条件为空 var res = await collection.Find(filter).ToListAsync(); } { //2.通过Id查询 var filter = filterBuilder.Eq(a => a.Id, ObjectId.Parse("60cac0979b3c533a5d1a06e1")); var res = await collection.Find(filter).ToListAsync(); } { //3.模糊查询 var filter = filterBuilder.Regex(a => a.ShortName,"/互联科技/"); var filter2 = filterBuilder.Regex(a => a.ShortName,"/^互联科技/"); var filter3 = filterBuilder.Regex(a => a.ShortName,"/联科技公司$/"); var res = await collection.Find(filter).ToListAsync(); } { //4.in查询 var filter = filterBuilder.In(a => ShortName, new[] { "电影视效中心","电影特效制作中心" }); var res = await collection.Find(filter).ToListAsync(); } { //5.and查询 var filter = filterBuilder.And( filterBuilder.Eq(a => a.ShortName,"互联科技"), filterBuilder.Eq(a => a.Name,"互联科技科技有限公司"), ); var res = await collection.Find(filter).ToListAsync(); } { //6.or查询 var filter = filterBuilder.Or( filterBuilder.Eq(a => a.ShortName,"电影视效中心"), filterBuilder.Eq(a => a.ShortName,"电影特效制作中心"), ); var res = await collection.Find(filter).ToListAsync(); } { //7.混合查询 //类似sql: Type=100 and OrgId>=2 and (Name like '%互联%' or ShortName='智能公司') and Code in ('SZN','SHL') var filter = filterBuilder.And( filterBuilder.Eq(a => a.Type, 100), filterBuilder.Gte(a => a.OrgId, 2), filterBuilder.Or( filterBuilder.Regex(a => a.Name,"/互联/"), filterBuilder.Eq(a => a.ShortName, "智能公司") ), filterBuilder.In(a => a.Code, new[] { "SZN","SHL" }) ); var res = await collection.Find(filter).ToListAsync(); }
2.2.新增
MongoDB脚本
//1.单条新增 db.Organizations.insertOne( { CreationTime: ISODate("2015-12-11T10:35:25.000Z"), CreatorUserId: NumberLong("1"), LastModificationTime: ISODate("2021-07-22T18:54:46.803Z"), LastModifierUserId: NumberLong("11949267"), IsDeleted: false, DeletionTime: null, DeleterUserId: null, CreatorUserName: null, LastModifierUserName: null, DeleterUserName: null, OrgId: NumberInt("2"), Name: "华强方特文化科技集团股份有限公司", ShortName: "华强方特集团", Code: "HQW", Type: NumberInt("100"), HeadUserId: NumberLong("11944818"), Sort: NumberInt("1"), ParentId: NumberInt("0"), IsActive: true, OrganizationLevel: NumberInt("1") } ); //2.多条新增 db.Organizations.insertMany( [{ CreationTime: ISODate("2015-12-11T10:35:25.000Z"), CreatorUserId: NumberLong("1"), LastModificationTime: ISODate("2021-07-22T18:54:46.803Z"), LastModifierUserId: NumberLong("11949267"), IsDeleted: false, DeletionTime: null, DeleterUserId: null, CreatorUserName: null, LastModifierUserName: null, DeleterUserName: null, OrgId: NumberInt("2"), Name: "华强方特文化科技集团股份有限公司", ShortName: "华强方特集团", Code: "HQW", Type: NumberInt("100"), HeadUserId: NumberLong("11944818"), Sort: NumberInt("1"), ParentId: NumberInt("0"), IsActive: true, OrganizationLevel: NumberInt("1") }] );
C#语法
//1.单条新增 await collection.InsertOneAsync(new Organizations { OrgId = 2, Name = "华强方特文化科技集团股份有限公司", IsActive = true, CreationTime = DateTime.Now, ... ... }); //2.多条新增 await collection.InsertManyAsync(new List<Organizations>());
2.3.更新
MongoDB脚本
//1.局部更新 db.Organizations.updateOne( { Code: "HQW" }, //查询条件 { $set: { "ShortName": "华强方特", IsActive: false }, //待更新字段 $push: { //在数组中插入元素 "Leaders": { "UserId": "ggggg", "IsMain": true } }, $currentDate: { LastModificationTime: true } //更新字段LastModificationTime为当前时间,若该字段不存在,则创建 } ) //2.多条更新 db.Organizations.updateMany( { LastModificationTime: {$gte:ISODate("2021-07-22T18:54:46.803Z")} }, //查询条件 { $set: { "ShortName": "华强方特", IsActive: false }, //待更新字段 $currentDate: { LastModificationTime: true } //更新字段LastModificationTime为当前时间,若该字段不存在,则创建 } ) //3.替换更新 db.Organizations.replaceOne( {"Code": "HQW"}, //查询条件 { //带替换的文档 "_id": ObjectId("60f7961699515da94c20296c"), CreationTime: ISODate("2015-12-11T10:35:25.000Z"), CreatorUserId: NumberLong("1"), LastModificationTime: ISODate("2021-07-22T18:54:46.803Z"), LastModifierUserId: NumberLong("11949267"), IsDeleted: false, DeletionTime: null, DeleterUserId: null, CreatorUserName: null, LastModifierUserName: null, DeleterUserName: null, OrgId: NumberInt("2"), Name: "华强方特文化科技集团股份有限公司", ShortName: "华强方特集团", Code: "HQW", Type: NumberInt("100"), HeadUserId: NumberLong("11944818"), Sort: NumberInt("1"), ParentId: NumberInt("0"), IsActive: true, OrganizationLevel: Num berInt("1") } )
C#语法
//1.局部更新 var filter = Builders<Organizations>.Filter.Eq(a => a.Id, ObjectId.Parse("60cac0979b3c533a5d1a06e1")); var updateBuilder = Builders<Organizations>.Update; var updates = new List<UpdateDefinition<Organizations>> { updateBuilder.Set(a=> a.ShortName,"华强方特"), updateBuilder.Set(a=> a.IsActive,true), updateBuilder.Push(a=> a.Leaders,new { UserId = "abc",IsMain = true}), updateBuilder.CurrentDate(a=>a.LastModificationTime) }; var res = await collection.UpdateOneAsync(filter, updateBuilder.Combine(updates)); //2.多条更新 var filter = Builders<Organizaionts>.Filter.Gte(a => a.LastModificationTime, DateTime.Now.AddDays(1)); var updateBuilder = Builders<Organizaionts>.Update; var updates = new List<UpdateDefinition<Organizaionts>> { updateBuilder.Set(a=> a.ShortName,"华强方特"), updateBuilder.Set(a=> a.IsActive,true), updateBuilder.CurrentDate(a=>a.LastModificationTime) }; var res = await collection.UpdateManyAsync(filter, updateBuilder.Combine(updates)); //3.替换更新 var replaceModel = new Organizaionts(){...}; var replaceRes = await collection.ReplaceOneAsync(Builders<Organizations>.Filter.Eq(a => Code, "HQW"), replaceModel);
3.嵌套文档结构
以员工扩展字段表为例,表结构如下图所示
//EmployeeFieldInfos { "_id": ObjectId("609cfe663242fa662691b34a"), "CreationTime": ISODate("2021-05-13T18:24:37.579Z"), "CreatorUserId": null, "LastModificationTime": ISODate("2021-05-13T18:24:37.583Z"), "LastModifierUserId": null, "IsDeleted": false, "DeletionTime": null, "DeleterUserId": null, "CreatorUserName": null, "LastModifierUserName": null, "DeleterUserName": null, "Categories": [ { "Code": "PersonalInfo", "Name": "个人信息设置", "Sort": NumberInt("1"), "Groups": [ { "Code": "BasicInfoGroup", "Name": "基本信息", "Sort": NumberInt("1"), "EmployeeFields": [ { "Code": "470a584e78f24c9da8c69e3cf2dabf48", "Name": "爱好", "IsSystemDefault": false, "FieldDataType": NumberInt("0"), "StringLength": NumberInt("125"), "Prompt": "最大支持125个字符", "IsRequried": false, "Sort": NumberInt("2") }, { "Code": "d7b5ad358cc64d0e8f9379eb1c9b23cf", "Name": "姓名", "IsSystemDefault": false, "FieldDataType": NumberInt("0"), "StringLength": NumberInt("125"), "Prompt": "最大支持125个字符", "IsRequried": false, "Sort": NumberInt("1") } ] }, { "Code": "CommunicationInfoGroup", "Name": "通讯信息", "Sort": NumberInt("2"), "EmployeeFields": [ ] } ] }, { "Code": "PostInfo", "Name": "岗位信息设置", "Sort": NumberInt("2"), "Groups": [ { "Code": "PostInfoGroup", "Name": "岗位信息", "Sort": NumberInt("1"), "EmployeeFields": [ ] }, { "Code": "ContractInfoGroup", "Name": "合同信息", "Sort": NumberInt("2"), "EmployeeFields": [ ] } ] } ] }
3.1.拆分查询
MongoDB脚本
通过“聚合管道”语法拆分子文档,将嵌套的内容拉平展示
db.EmployeeFieldInfos.aggregate([{ $unwind: '$Categories' //拆分的子文档 }, { $unwind: '$Categories.Groups' //拆分的子文档 }, { $unwind: '$Categories.Groups.EmployeeFields' //拆分的子文档 }, { $match: { 'Categories.Code': { $in: ['PersonalInfo'] }, 'Categories.Groups.Code': { $in: ['BasicInfoGroup'] }, 'Categories.Groups.EmployeeFields.IsDeleted': false } }, { $addFields: { //临时变量 'Code': '$Categories.Groups.EmployeeFields.Code', 'Name': '$Categories.Groups.EmployeeFields.Name', 'IsSystemDefault': '$Categories.Groups.EmployeeFields.IsSystemDefault', 'FieldDataType': '$Categories.Groups.EmployeeFields.FieldDataType', 'OptionsDefinitionCode': '$Categories.Groups.EmployeeFields.OptionsDefinitionCode', 'StringLength': '$Categories.Groups.EmployeeFields.StringLength', 'Prompt': '$Categories.Groups.EmployeeFields.Prompt', 'IsRequired': '$Categories.Groups.EmployeeFields.IsRequired', 'Sort': '$Categories.Groups.EmployeeFields.Sort', 'DefaultValue': '$Categories.Groups.EmployeeFields.DefaultValue', 'IsActive': '$Categories.Groups.EmployeeFields.IsActive', 'IsDeleted': '$Categories.Groups.EmployeeFields.IsDeleted', 'CategoryCode': '$Categories.Code', 'CategoryName': '$Categories.Name', 'CategorySort': '$Categories.Sort', 'GroupCode': '$Categories.Groups.Code', 'GroupName': '$Categories.Groups.Name', 'GroupSort': '$Categories.Groups.Sort', 'GroupSystemDefault': '$Categories.Groups.IsSystemDefault', 'GroupMultiple': '$Categories.Groups.IsMultiple' } }, { $project: { //表示需要显示或隐藏的属性列表,0表示隐藏,1表示显示。此处可使用上面定义的临时变量 '_id': 0, //_id属性属于文档顶层元素,不需要使用临时变量 'Code': 1, //当前Code属于嵌套子文档中的元素,需要使用临时变量 'Name': 1, 'IsSystemDefault': 1, 'FieldDataType': 1, 'OptionsDefinitionCode': 1, 'StringLength': 1, 'Prompt': 1, 'IsRequired': 1, 'Sort': 1, 'DefaultValue': 1, 'IsActive': 1, 'IsDeleted': 1, 'CategoryCode': 1, 'CategoryName': 1, 'CategorySort': 1, 'GroupCode': 1, 'GroupName': 1, 'GroupSort': 1, 'GroupSystemDefault': 1, 'GroupMultiple': 1 } }]); //结果实例: // 1 { "IsDeleted": false, "Code": "470a584e78f24c9da8c69e3cf2dabf48", "Name": "爱好", "IsSystemDefault": false, "FieldDataType": NumberInt("0"), "StringLength": NumberInt("125"), "Prompt": "最大支持125个字符", "Sort": NumberInt("2"), "CategoryCode": "PersonalInfo", "CategoryName": "个人信息设置", "CategorySort": NumberInt("1"), "GroupCode": "BasicInfoGroup", "GroupName": "基本信息", "GroupSort": NumberInt("1"), ... ... } // 2 { "IsDeleted": false, "Code": "d7b5ad358cc64d0e8f9379eb1c9b23cf", "Name": "姓名", "IsSystemDefault": false, "FieldDataType": NumberInt("0"), "StringLength": NumberInt("125"), "Prompt": "最大支持125个字符", "Sort": NumberInt("1"), "CategoryCode": "PersonalInfo", "CategoryName": "个人信息设置", "CategorySort": NumberInt("1"), "GroupCode": "BasicInfoGroup", "GroupName": "基本信息", "GroupSort": NumberInt("1"), ... ... }
C#语法
MongoDb BsonDocument转json时,因为含有很多mongo特有的属性,导致json不是合法的,需要转换为.net可识别的对象,再转为json
单个BsonDocument的转换方式:var dotNetValue = BsonTypeMapper.MapToDotNetValue(doc);
BsonDocument数组的转换方式: var dotNetObjList = bsonDocList.ConvertAll(BsonTypeMapper.MapToDotNetValue);
var collection = BsonDocumentCollection; var pipelineJsons = new List<string> { "{$unwind:'$Categories'}", "{$unwind:'$Categories.Groups'}", "{$unwind:'$Categories.Groups.EmployeeFields'}", "{$match:{'Categories.Code':{$in:['PersonalInfo']},'Categories.Groups.Code':{$in:['BasicInfoGroup']},'Categories.Groups.EmployeeFields.IsDeleted':false}}", "{$addFields:{'Code':'$Categories.Groups.EmployeeFields.Code','Name':'$Categories.Groups.EmployeeFields.Name','IsSystemDefault':'$Categories.Groups.EmployeeFields.IsSystemDefault','FieldDataType':'$Categories.Groups.EmployeeFields.FieldDataType','ExtensionValue':'$Categories.Groups.EmployeeFields.ExtensionValue','IsMultipleChoice':'$Categories.Groups.EmployeeFields.IsMultipleChoice','OptionsDefinitionCode':'$Categories.Groups.EmployeeFields.OptionsDefinitionCode','StringLength':'$Categories.Groups.EmployeeFields.StringLength','Prompt':'$Categories.Groups.EmployeeFields.Prompt','IsRequired':'$Categories.Groups.EmployeeFields.IsRequired','ReadOnly':'$Categories.Groups.EmployeeFields.ReadOnly','Sort':'$Categories.Groups.EmployeeFields.Sort','DefaultValue':'$Categories.Groups.EmployeeFields.DefaultValue','IsActive':'$Categories.Groups.EmployeeFields.IsActive','IsEdit':'$Categories.Groups.EmployeeFields.IsEdit','IsHide':'$Categories.Groups.EmployeeFields.IsHide','IsDeleted':'$Categories.Groups.EmployeeFields.IsDeleted','CategoryCode':'$Categories.Code','CategoryName':'$Categories.Name','CategorySort':'$Categories.Sort','GroupCode':'$Categories.Groups.Code','GroupName':'$Categories.Groups.Name','GroupSort':'$Categories.Groups.Sort','GroupSystemDefault':'$Categories.Groups.IsSystemDefault','GroupMultiple':'$Categories.Groups.IsMultiple','GroupReadOnly':'$Categories.Groups.ReadOnly'}}", "{$project:{'_id':0,'Code':1,'Name':1,'IsSystemDefault':1,'FieldDataType':1,'ExtensionValue':1,'IsMultipleChoice':1,'OptionsDefinitionCode':1,'StringLength':1,'Prompt':1,'IsRequired':1,'ReadOnly':1,'Sort':1,'DefaultValue':1,'IsActive':1,'IsEdit':1,'IsHide':1,'IsDeleted':1,'CategoryCode':1,'CategoryName':1,'CategorySort':1,'GroupCode':1,'GroupName':1,'GroupSort':1,'GroupSystemDefault':1,'GroupMultiple':1,'GroupReadOnly':1}}" }; var stages = pipelineJsons.Select(a => new JsonPipelineStageDefinition<BsonDocument, BsonDocument>(a)); var pipeline = new PipelineStagePipelineDefinition<BsonDocument, BsonDocument>(stages); var res = await collection.Aggregate(pipeline).ToListAsync(); if (res == null) { return new List<EmployeeFieldDto>(); } var dotNetObjList = res.ConvertAll(BsonTypeMapper.MapToDotNetValue); var json = JsonConvert.SerializeObject(dotNetObjList); return Newtonsoft.Json.JsonConvert.DeserializeObject<List<EmployeeFieldDto>>(json);
3.2.子文档新增
MongoDB脚本
$push
db.EmployeeFieldInfos.updateOne({}, { $push: { "Categories.$[i].Groups.$[j].EmployeeFields": { "IsDeleted": false, "Code": "d7b5ad358cc64d0e8f9379eb1c9b23cf", "Name": "姓名", "IsSystemDefault": false, "FieldDataType": NumberInt("0"), "StringLength": NumberInt("125"), "Prompt": "最大支持125个字符", "Sort": NumberInt("1"), "CategoryCode": "PersonalInfo", "CategoryName": "个人信息设置", "CategorySort": NumberInt("1"), "GroupCode": "BasicInfoGroup", "GroupName": "基本信息", "GroupSort": NumberInt("1") } } }, { arrayFilters: [{ "i.Code": "PersonalInfo" }, { "j.Code": "BasicInfoGroup" }] })
C#语法
var collection = Collection; var update = Builders<EmployeeFieldInfo>.Update.Push("Categories.$[i].Groups.$[j].EmployeeFields", new EmployeeFieldInfo()); var updateOption = new UpdateOptions { ArrayFilters = new List<ArrayFilterDefinition<EmployeeFieldInfo>> { new BsonDocument("i.Code", categoryCode), new BsonDocument("j.Code", groupCode) } }; var res = await collection.UpdateOneAsync(Builders<EmployeeFieldInfo>.Filter.Empty, update, updateOption); if (res.MatchedCount == 0) { throw new ResultException(Result.FromError("新增失败")); } return res;
3.3.子文档更新
MongoDB脚本
$set
arrayFilters限制:对相同数组索引的条件,需要通过花括号包在一个对象内
//1.修改部分属性 db.EmployeeFieldInfos.updateOne({}, { $set: { "Categories.$[i].Groups.$[j].EmployeeFields.$[k].Name": "姓名" } }, { arrayFilters: [{ "i.Code": "PersonalInfo" }, { "j.Code": "BasicInfoGroup" }, { //对索引k的多个条件,需要包含在同一个json对象内,否则会报错:Found multiple array filters with the same top-level field name k "k.Code": "Name", "k.IsDeleted": true }] }) //2.修改多个属性 db.EmployeeFieldInfos.updateOne({}, { $set: { "Categories.$[i].Groups.$[j].EmployeeFields.$[k].Name": "姓名", "Categories.$[i].Groups.$[j].EmployeeFields.$[k].IsActive": true } }, { //嵌套文档过滤条件 arrayFilters: [{ "i.Code": "PersonalInfo" }, { "j.Code": "BasicInfoGroup" }, { //对索引k的多个条件,需要包含在同一个json对象内,否则会报错:Found multiple array filters with the same top-level field name k "k.Code": "Name", "k.IsDeleted": true }] }) //3.修改整个嵌套文档 db.EmployeeFieldInfos.update({}, { $set: { "Categories.$[i].Groups.$[j].EmployeeFields.$[k]": { "IsDeleted": false, "Code": "d7b5ad358cc64d0e8f9379eb1c9b23cf", "Name": "姓名", "IsSystemDefault": false, "FieldDataType": NumberInt("0"), "StringLength": NumberInt("125"), "Prompt": "最大支持125个字符", "Sort": NumberInt("1"), "CategoryCode": "PersonalInfo", "CategoryName": "个人信息设置", "CategorySort": NumberInt("1"), "GroupCode": "BasicInfoGroup", "GroupName": "基本信息", "GroupSort": NumberInt("1") } } }, { arrayFilters: [{ "i.Code": "PersonalInfo" }, { "j.Code": "BasicInfoGroup" }, { "k.Code": "Name", "k.IsDeleted": true }] })
C#语法
//1.修改一个属性 var collection = Collection; var update = Builders<EmployeeFieldInfo>.Update.Set("Categories.$[i].Groups.$[j].EmployeeFields.$[k].Name", "姓名"); var updateOption = new UpdateOptions { ArrayFilters = new List<ArrayFilterDefinition<EmployeeFieldInfo>> { new BsonDocument("i.Code", categoryCode), new BsonDocument("j.Code", groupCode), new BsonDocument(){ { "k.Code", field.Code}, { "k.IsDeleted",false} } } }; var res = await collection.UpdateOneAsync(Builders<EmployeeFieldInfo>.Filter.Empty, update, updateOption); if (res.MatchedCount == 0) { throw new ResultException(Result.FromError("更新失败")); } return res; //2.修改多个属性 var collection = Collection; var updateBuilder = Builders<Employee>.Update; var updates = updateBuilder.Combine(new List<UpdateDefinition>{ Builders<EmployeeFieldInfo>.Update.Set("Categories.$[i].Groups.$[j].EmployeeFields.$[k].Name", "姓名"), Builders<EmployeeFieldInfo>.Update.Set("Categories.$[i].Groups.$[j].EmployeeFields.$[k].IsActive", true) }); var updateOption = new UpdateOptions { ArrayFilters = new List<ArrayFilterDefinition<EmployeeFieldInfo>> { new BsonDocument("i.Code", categoryCode), new BsonDocument("j.Code", groupCode), new BsonDocument(){ { "k.Code", field.Code}, { "k.IsDeleted",false} } } }; var res = await collection.UpdateOneAsync(Builders<EmployeeFieldInfo>.Filter.Empty, updates, updateOption); if (res.MatchedCount == 0) { throw new ResultException(Result.FromError("更新失败")); } return res; //3.修改整个嵌套文档 var collection = Collection; var update = Builders<EmployeeFieldInfo>.Update.Set("Categories.$[i].Groups.$[j].EmployeeFields.$[k]", new EmployeeFieldInfo()); var updateOption = new UpdateOptions { ArrayFilters = new List<ArrayFilterDefinition<EmployeeFieldInfo>> { new BsonDocument("i.Code", categoryCode), new BsonDocument("j.Code", groupCode), new BsonDocument(){ { "k.Code", field.Code}, { "k.IsDeleted",false} } } }; var res = await collection.UpdateOneAsync(Builders<EmployeeFieldInfo>.Filter.Empty, update, updateOption); if (res.MatchedCount == 0) { throw new ResultException(Result.FromError("更新失败")); } return res;
3.4.子文档删除
MongoDB脚本
$pull
//删除PersonalInfo分类下、BasicInfoGroup分组下、Code为"Name"的员工字段子文档数据 db.EmployeeFieldInfos.updateOne({}, { $pull: { "Categories.$[i].Groups.$[j].EmployeeFields": { "Code": "Name", "IsActive": true } } }, { arrayFilters: [{ "i.Code": "PersonalInfo" }, { "j.Code": "BasicInfoGroup" }] })
C#语法
var collection = Collection; var update = Builders<EmployeeFieldInfo>.Update.Pull("Categories.$[i].Groups.$[j].EmployeeFields", new BsonDocument{ {"Code", "Name"}, {"IsActive", true} }); var updateOption = new UpdateOptions { ArrayFilters = new List<ArrayFilterDefinition<EmployeeFieldInfo>> { new BsonDocument("i.Code", categoryCode), new BsonDocument("j.Code", groupCode), new BsonDocument(){ { "k.Code", field.Code}, { "k.IsDeleted",false} } } }; var res = await collection.UpdateOneAsync(Builders<EmployeeFieldInfo>.Filter.Empty, update, updateOption); if (res.MatchedCount == 0) { throw new ResultException(Result.FromError("更新失败")); } return res;