去年三月底入职上海的一家互联网公司,由于项目使用的是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 == ).TestTwoList.FirstOrDefault(t=>t.TestTwoId==));
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, );
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, );

            var ArrayFilters = new List<ArrayFilterDefinition>();
ArrayFilters.Add(new JsonArrayFilterDefinition<Test>("{\"i.TestOneId\":{$eq:"+ + "}}"));
ArrayFilters.Add(new JsonArrayFilterDefinition<Test>("{\"j.TestTwoId\":{$eq:" + + "}}")); 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操作!!!!!

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

MongoDB的一些操作技巧的更多相关文章

  1. 【翻译】MongoDB指南/CRUD操作(二)

    [原文地址]https://docs.mongodb.com/manual/ MongoDB CRUD操作(二) 主要内容: 更新文档,删除文档,批量写操作,SQL与MongoDB映射图,读隔离(读关 ...

  2. 【翻译】MongoDB指南/CRUD操作(一)

    [原文地址]https://docs.mongodb.com/manual/ MongoDB CRUD操作(一) 主要内容:CRUD操作简介,插入文档,查询文档. CRUD操作包括创建.读取.更新和删 ...

  3. 用Excel做出比肩任务管理软件的操作技巧

    用Excel做出比肩任务管理软件的操作技巧 在项目管理中,网上有各种各样的工具可以选择,到底用哪个,曾一度困扰着我.我是一个有轻度强迫症的人,总是喜欢试用各种各样的系统,以比较他们之间的不同,试图选择 ...

  4. MongoDB的CRUD操作

    1. 前言 在上一篇文章中,我们介绍了MongoDB.现在,我们来看下如何在MongoDB中进行常规的CRUD操作.毕竟,作为一个存储系统,它的基本功能就是对数据进行增删改查操作. MongoDB中的 ...

  5. MongoDB各种查询操作详解

    这篇文章主要介绍了MongoDB各种查询操作详解,包括比较查询.关联查询.数组查询等,需要的朋友可以参考下   一.find操作 MongoDB中使用find来进行查询,通过指定find的第一个参数可 ...

  6. Jquery数组操作技巧

    Jquery对数组的操作技巧. 1. $.each(array, [callback]) 遍历[常用]  解释: 不同于例遍 jQuery 对象的 $.each() 方法,此方法可用于例遍任何对象(不 ...

  7. mongodb的常用操作

    对于nosql之前工作中有用到bekerlydb,最近开始了解mongodb,先简单写下mongodb的一些常用操作,当是个总结: 1.mongodb使用数据库(database)和集合(collec ...

  8. Vi操作技巧

    Vi操作技巧: :nu    显示当前所在行的行号 :set nu    显示全部行号 :set nonu        取消显示行号 /字符串    查询字符串,按n查询下一个,按N查询上一个 持续 ...

  9. vim常用操作技巧与配置

    vi是linux与unix下的常用文本编辑器,其运行稳定,使用方便,本文将分两部分对其常用操作技巧和配置进行阐述,其中参考了网上的一些文章,对作者表示感谢 PART1 操作技巧 说明: 以下的例子中  ...

随机推荐

  1. kali2 install Nessus

    注册: https://www.tenable.com/products/nessus-home 安装: 设置登录用户名,密码,输入注册码:

  2. hdu 4300 kmp算法扩展

    Clairewd’s message Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  3. vue v-show与v-for同时配合v-bind使用并在href中传递多个参数的使用方法

    最近在项目中,因为还没使用前端构建工具,还在使用vue+jquery方法渲染页面 碰到几个小问题,在此记录下作为vue学习之路上的一个小知识点 需求:1.数据列表存在与否状态,没有数据显示默认提示,有 ...

  4. 进击JavaScript核心 --- (2)函数和预解析机制

    一.函数 每个函数都是 Function类型的实例,也具有属性和方法.由于函数也是一个对象,因此函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定 1.函数的定义方式 (1).函数声明 fun ...

  5. Careercup | Chapter 6

    6.2 There is an 8x8 chess board in which two diagonally opposite corners have been cut off. You are ...

  6. Xamarin XAML语言教程XAML文件结构与解析XAML

    Xamarin XAML语言教程XAML文件结构与解析XAML XAML文件结构 在上文中,我们创建XAML文件后,会看到类似图1.16所示的结构 图1.16  结构 其中,.xaml文件和.xaml ...

  7. 转载:P2P技术原理及应用(2)

    转载allen303allen的空间 在Gnutella网络中存在以下问题: 冗余消息多,对带宽的消耗存在一定的浪费.Gnutella网络协议采用泛洪式(Flooding)消息传播机制,这种消息传播机 ...

  8. spring的自动装配Bean与自动检测Bean

    spring可以通过编写XML来配置Bean,也可以通过使用spring的注解来装配Bean. 1.自动装配与自动检测: 自动装配:让spring自动识别如何装配bean的依赖关系,减少对<pr ...

  9. Delphi Helper Record Class

    unit Unit1; {$DEFINE USESGUIDHELP} interface implementation {$IFDEF USESGUIDHELP} uses System.SysUti ...

  10. input 对伪元素(:before :after)的支持情况

    最近做一个自定义视觉效果的Switch组件,用到了 input:radio 和 label,并在label里用伪元素 :before 模拟状态的切换效果. 但是同事评审的时候说可以不用label,直接 ...