去年三月底入职上海的一家互联网公司,由于项目使用的是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. BZOJ3083 遥远的国度 【树剖】

    题目 zcwwzdjn在追杀十分sb的zhx,而zhx逃入了一个遥远的国度.当zcwwzdjn准备进入遥远的国度继续追杀时,守护神RapiD阻拦了zcwwzdjn的去路,他需要zcwwzdjn完成任务 ...

  2. 刷题总结——Tree2cycle(hdu4714 树形dp)

    题目: A tree with N nodes and N-1 edges is given. To connect or disconnect one edge, we need 1 unit of ...

  3. [USACO12DEC]第一!First! (Trie树,拓扑排序)

    题目链接 Solution 感觉比较巧的题啊... 考虑几点: 可以交换无数次字母表,即字母表可以为任意形态. 对于以其他字符串为前缀的字符串,我们可以直接舍去. 因为此时它所包含的前缀的字典序绝对比 ...

  4. nvm、node、npm安装以及pycharm配置eslint

    nvm.node.npm之间的区别 1. nvm的官方叫法:nodejs版本管理工具. nvm相当于是家长,一个家长可以管理多个孩子. 也就是说:一个nvm可以管理很多node版本和npm版本. 2. ...

  5. bzoj 2798 [Poi2012]Bidding 博弈论+dp

    题目大意 A和B两个人在玩一个游戏,这个游戏是他们轮流操作一对整数(x,y). 初始时(x,y)=(1,0),可以进行三种操作: 将(x,y)变成(1,x+y). 将(x,y)变成(2x,y). 将( ...

  6. 'Add Solution': A timeout has occurred while invoking commands in SharePoint host process.

    一.问题描述: 在部署SharePoint solution的时候,出现Time out 的问题,错误提示: Error occurred in deployment step 'Add Soluti ...

  7. 【CF1016B】Segment Occurrences(模拟)

    题意:给定两个串s和t,多次询问s的一个区间[l ,r]中有多少个子串与t串相同 len<=1e3,q<=1e5 思路:前缀和 #include<cstdio> #includ ...

  8. 【CF652C】Foe Pairs(线性扫描)

    题意:给你1-n的一个排列和m组数对,问有多少区间不包含任意一个数对. (1 ≤ n, m ≤ 3·105) 思路:数据范围过大,不能用容斥原理 f[i]表示以位置i上的数为左端点,右端点最小到哪里 ...

  9. 转 Centos下安装apahce的configure: error: APR not found. Please read the documentation解决办法

    转自: http://www.cnblogs.com/Anker/p/3355573.html 今天从Apache官网上http://httpd.apache.org/下载httpd web服务器,由 ...

  10. 24深入理解C指针之---指针和数组

    一.指针和数组 #include <stdio.h> int main(int argc, char **argv) { ] = {, , , , ,}; int *ptrVector = ...