zoukankan      html  css  js  c++  java
  • MongoDB的一些操作技巧

    去年三月底入职上海的一家互联网公司,由于项目使用的是MongoDB数据库所以有机会接触了MongoDB。在项目的开发过程中使用系统原有的一些方法查询MongoDB感觉很费力,用起来也不爽,所以私下里就自己学了一些C#查询MongoDB的方法。

    先说一些MongoDB的内嵌数组查询,公司原有的方法是使用Map进行聚合,这导致查询效率底下。多个项目组的成员都有抱怨。

    在研究MongoDB测试用例后总结出使用投影技术来替换Map的方法:

    public class Test
    {
    
           public ObjectId Id{get;set;}        
           public string AAA{get;set;}
            public IList<TestOne> TestOneList{get;set;}
    
    }
    
    public class TestOne
    {
    
         public long TestOneId{get;set;}
    public string Name{get;set;}
    public IList<TestTwo> TestTwoList{get;set;} }

    public class TestTwo
    {
    public long TestTwoId{get;set;}
    }

    假定有这么一个数据结构 我想查询指定的TestOne 我们就可以利用投影技术来实现

    var projection = new ProjectionDefinitionBuilder<Test>();
    var pp = projection.Expression(r =>
                    r.TestOneList.FirstOrDefault(s => s.TestOneId == 123));
     
    dbContext.Get(filter, new FindOptions<Test, TestOne>()
    {
    Projection = pp
    });

    这样我们就可以直接拿到指定的TestOne 了。同样对于多层嵌套 我们可以在Expression里一层一层往下写 

    var pp = projection.Expression(r =>
                    r.TestOneList.FirstOrDefault(s => s.TestOneId == 123).TestTwoList.FirstOrDefault(t=>t.TestTwoId==333));
    dbContext.Get(filter, new FindOptions<Test, TestTwo>()
    {
    Projection = pp
    });

    在公司的测试服务器上相较map方式性能提升近10倍 。

    在MongoDB中我们常常会面临一个问题,一个文档的数据量过大,譬如 我们TestTwoList里的数据量达到万级别,这个时候我们查询一个Test数据的耗时肯定会非常的大,即便是我们放到Redis等缓存中依然会很慢。那么有什么方法能够优化呢?

    在实际使用过程中我们的各个业务不同对于Test里的数据需要也不同,比如业务A只需要Test中的TestOne 的Name信息,业务B只需要Test中的AAA信息。那么我们可以根据实际需要来进行投影以获取我们实际需要的数据,而不是获取所有的数据。

    var rr = Builders<Test>.Filter.Eq(r=>r.Id, 1123123);
                var project =new ProjectionDefinitionBuilder<Test>();
                var pp = project.Include("Name");
                var ss = dbContext.Get(rr, new FindOptions<Test, 自定义类型>()
                {
                    Projection = pp
                });

    这样我们就可以只拿我们需要的数据。

    Linq 查询MongoDB。我们拿到Query后可以使用Linq进行各种查询,group 等。非常实用。

    最后呢推荐一种 多层嵌套数据操作方法,在多层数组嵌套中最难搞得就是定位的问题。好在MongoDB官方在3.6版本提供了ArrayFilters ,极大的方便了开发人员

    var filterBuiler = Builders<Test>.Filter;
               
                var filter = filterBuiler.Eq(r => r.Id, 598882505);
    
                var ArrayFilters = new List<ArrayFilterDefinition>();
                ArrayFilters.Add(new JsonArrayFilterDefinition<Test>("{"i.TestOneId":{$eq:"+ 598882571 + "}}"));
                ArrayFilters.Add(new JsonArrayFilterDefinition<Test>("{"j.TestTwoId":{$eq:" + 598882573 + "}}"));
    
                UpdateOptions updateOptions=new UpdateOptions();
                updateOptions.ArrayFilters = ArrayFilters;
                var update = new UpdateDefinitionBuilder<Test>();
                var updatef = update.Set("TestOneList.$[i].TestTwoList.$[j].xxxxx", "哈哈");
               await dbContext.UpdateAsync(filter, updatef, updateOptions);

    这种方法只被3.6版本的数据库支持

    使用MongoDB的同仁一定要记得 MongoDB中对于整数,长整数,双精度浮点数有一个Inc操作!!!!!

    吐槽一下:不知道为什么总能遇到一些拥有迷之自信的程序员? 不知道各位同仁有没有遇到过拥有迷之自信的程序员?

  • 相关阅读:
    python注释方法以及编码问题
    python数据类型和变量
    JavaScript必须了解的知识点总结。
    javaScript语法总结
    美图WEB开放平台环境配置
    变点问题的统计推新及其在全融中的应用 谭常春
    Structural breaks in time series
    多种单位根检验法的比较研究 房林邹卫星
    1-出口数据的平稳性分析
    时间序列中的结构突变与单位根检验
  • 原文地址:https://www.cnblogs.com/pjjwpc/p/8842178.html
Copyright © 2011-2022 走看看