• MongoDB 系列(二) C# 内嵌元素操作 聚合使用


    
    

    "_id" : "639d8a50-7864-458f-9a7d-b72647a3d226",
    "ParentGuid" : "00000000-0000-0000-0000-000000000000",
    "Name" : "汉字",
    "Describe" : "",
    "Enable" : true,
    "Level" : 2,
    "Subject" : "语文",
    "Exams" : [ { "ExamGuid" : "6635e1c6-2a22-404e-b58c-97ed9fc49ffc", "Grade" : "G2", "Questions" : [ { "_id" : "97eeeaaa-5902-4c11-bcdb-8b7a70485753" }, { "_id" : "628d5613-90b1-44fa-b02d-4074e86aa751" } ] }, { "ExamGuid" : "b1e72692-6b63-4d98-a4bb-1b48765e7a96", "Grade" : "G1", "Questions" : [ { "_id" : "628d5613-90b1-44fa-b02d-4074e86aa751" } ] } ]
     

    场景1:给内嵌集合的元素添加一个新的元素

     1.首先根据筛选条件确定元素

    1  var filter = Builders<CustomKnowPoint>.Filter.And(
    2                          Builders<CustomKnowPoint>.Filter.Eq(o => o.Id, "639d8a50-7864-458f-9a7d-b72647a3d226"),
    3                          Builders<CustomKnowPoint>.Filter.Eq("Exams.ExamGuid", "6635e1c6-2a22-404e-b58c-97ed9fc49ffc"));

    CustomKnowPoint为MongoDB映射的对象  Builders<CustomKnowPoint>.Filter.And 方法的参数是一个param[]数组,意思是将所有的过滤条件用And且的关系合并

    var update = Builders<CustomKnowPoint>.Update.Push("Exams.$.Questions", new QuestionGuid(Guid.NewGuid().ToString()));
    this.Collection.FindOneAndUpdate(filter, update);

    2.执行后Questions内嵌集合就会在元素的末尾添加一条新的记录

    场景2:内嵌集合的元素进行删除

     

    过滤条件同上面的新增一样 通过对象本身的Id和内嵌元素的ExamGuid固定内嵌文档,移除文档的具体Filter对象是移除对象本身Builders<QuestionGuid>.Filter而不是Builders<CustomKnowPoint>.Filter

    var update = Builders<CustomKnowPoint>.Update.PullFilter("Exams.$.Questions", Builders<QuestionGuid>.Filter.Eq("_id", "628d5613-90b1-44fa-b02d-4074e86aa751"));
    this.Collection.FindOneAndUpdate(filter, update);

    场景3:聚合使用

    MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。表达式:处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档。

    "_id" : "639d8a50-7864-458f-9a7d-b72647a3d226",
    "ParentGuid" : "00000000-0000-0000-0000-000000000000",
    "Name" : "汉字",
    "Describe" : "",
    "Enable" : true,
    "Level" : 2,
    "Subject" : "语文",
    "Exams" : [ 
            {
                "ExamGuid" : "6635e1c6-2a22-404e-b58c-97ed9fc49ffc",
                "Grade" : "G2",
                "Questions" : [ 
                    {
                        "_id" : "97eeeaaa-5902-4c11-bcdb-8b7a70485753"
                    },
                    {
                        "_id" : "628d5613-90b1-44fa-b02d-4074e86aa751"
                    }
                ]
            }
        ]

    当我们只需要返回内嵌文档部分的时候 这种场景下我们就可以用到聚合来操作了 执行MongoDB语句

    db.KnowPoint.aggregate(
    [
        { 
            /*此处$unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。*/
            $unwind : "$Exams" 
        }, 
        { 
        /*此处$match :过滤文档筛选条件。*/ $match : {
    "Exams.ExamGuid" : "6635e1c6-2a22-404e-b58c-97ed9fc49ffc" } }, {
        /*此处group 分组。*/ $group : { _id : {
                /*此处按照各种属性拼凑分组 将各属性组成一个Id的属性*/
    "_id" : "$_id", "ParentGuid" : "$ParentGuid", "Name" : "$Name", "Enable" : "$Enable", "Level" : "$Level", "Subject" : "$Subject" }, "Exams" : {
                /*此处push将之前分组的Exams再写进去*/
    "$push" : "$Exams" } } } ])

    相应的C# 驱动程序

                List<string> keys = new List<string>() { "_id", "ParentGuid", "Name", "Enable", "Level", "Subject" };
                var stages = new List<IPipelineStageDefinition>();
                #region 过滤条件
                stages.Add(new JsonPipelineStageDefinition<BsonDocument, BsonDocument>
                   (
                       "{" +
                                "$unwind:"$Exams"" +
                       "}"
                   ));
                stages.Add(new JsonPipelineStageDefinition<BsonDocument, BsonDocument>
                    (
                        "{" +
                                "$match:" +
                                "{" +
                                        ""Exams.ExamGuid":" +
                                        "{" +
                                                    "$in:" + JsonConvert.SerializeObject(new List<string>() { "6635e1c6-2a22-404e-b58c-97ed9fc49ffc"}) +
                                        "}" +
                                "}" +
                        "}"
                    ));
    
              
                stages.Add(new JsonPipelineStageDefinition<BsonDocument, BsonDocument>
                    (
                        "{" +
                                 "$group:" +
                                             "{" +
                                                        "_id:{ " + string.Join(",", keys.Select(o => """ + o + "":"$" + o + """).ToList()) + "  }," +
                                                        "Exams:{$push:"$Exams"}" +
                                             "}" +
                        "}"
                    ));
                #endregion
    
                var pipeline = new PipelineStagePipelineDefinition<BsonDocument, BsonDocument>(stages);
    
                var result = this.Context
                                          .DbSet<BsonDocument>(nameof(KnowPoint))
                                          .Aggregate(pipeline)
                                          .ToList()
  • 相关阅读:
    NYOJ 542 试制品(第五届河南省省赛)
    714-Card Trick
    716-River Crossing
    1248-海岛争霸
    51Nod
    51Nod
    NYOJ_1274_信道安全
    ZZNU 2095 : 我只看看不写题
    前端-HTML标签
    python 17篇 unittest单元测试框架
  • 原文地址:https://www.cnblogs.com/hfdel/p/7412757.html
Copyright © 2020-2023  润新知