.Net-Mongodb学习大全网址
http://www.yuanjiaocheng.net/csharpmongo/16.html
介绍
在上一篇文章中,我们继续探索MongoDb .NET驱动程序中的数据序列化。 我们查看了各种属性,如BsonIgnore,BsonRepresentation或BsonIgnoreIfNull。 数据序列化不是太复杂,只要MongoDb中的文档遵守一些模式,就像在我们的演示餐厅和邮政编码集合。 一旦我们必须反序列化一组无序的文档,那么我们可能需要实现我们自己的序列化,事情变得更加复杂。 这是追踪模式的另一个原因,即使MongoDb文档是无模式的。
在这篇文章中,我们将介绍.NET驱动程序中的查询技术。 我们将基于我们以前开始构建的演示.NET代码。
Find方法
在撰写本文时,T界面的IMongoCollection提供了以下Find方法:
Find:一种扩展方法,使我们能够以流畅的方式构建查询,即我们可以链接与搜索相关的各种其他方法
FindSync:一种同步查找方法,它返回一个游标,并不像Find扩展方法那么灵活
FindAsync:一个异步的,即等待版本的FindSync
所有这些功能都接受基本上遵循两种不同格式的过滤器,我们已经看到了两个示例:FilterDefinition或返回true的LINQ语句。 我发现Find扩展方法是上述最灵活的,因为它打开了以流畅的方式(如排序和限制)将其他与搜索相关的查询附加到其中的可能性。 因此,我会在这篇文章中坚持下去,但是要注意替代方案是很好的。
findOne和findall
回想一下,findOne()提供了一种快速了解Mongo shell中的文档结构的方法。 我们如何在C#中写同一个? 简单:
|
1
2
|
ZipCodeDb firstZip = modelContext.ZipCodes.Find(z => true).FirstOrDefault();RestaurantDb firstRestaurant = modelContext.Restaurants.Find(r => true).FirstOrDefault(); |
我们在LINQ语句中没有任何过滤返回true。 它相当于SQL中没有where子句的SELECT * FROM语句。 然后,我们只需附加熟悉的FirstOrDefault方法来获取第一个文档。
相反,如果我们要检索所有没有任何过滤器的文档,那么我们只需应用ToList终端运算符:
|
1
2
|
List<ZipCodeDb> allZipCodes = modelContext.ZipCodes.Find(z => true).ToList();List<RestaurantDb> allRestaurants = modelContext.Restaurants.Find(r => true).ToList(); |
当您轻触IntelliSense提供的功能时,您会注意到FirstOrDefault和ToList方法都具有异步版本:FirstOrDefaultAsync和ToListAsync。 在MongoDb库中,这是一个很常见的功能,它同时具有异步版本。
过滤基础知识
如前所述,过滤可以使用特定于MongoDb库的FilterDefinition对象或更一般的LINQ表达式来构建。 .NET程序员会意识到LINQ我相信我们从FilterDefinitionBuilder开始。 在我的经验中,有一些复杂的过滤器定义只能用这个特定的语法来表达,所以即使你是一个LINQ的狂热者也是很好的。
过滤器定义使用通用Builders静态类及其Filter属性构建。 Builders类是构建一些不同定义对象的网关,FilterDefinitions只是其中之一。 Filter属性然后具有大量方法来帮助我们构建查询。 我们以前已经看过一个例子:
|
1
2
|
ModelContext modelContext = ModelContext.Create(new ConfigFileConfigurationRepository(), new AppConfigConnectionStringRepository());var filter = Builders<RestaurantDb>.Filter.Eq(r => r.Borough, "Brooklyn"); |
如果您在Visual Studio中键入“Builders.Filter”,则IntelliSense将会提供或多或少对应于本系列中查看的查询操作符的多种功能。 例如。 Gt函数映射到$ gt运算符,Not to $ not等。在许多情况下,通过名称来猜测函数的目的并不难,如Gt = GreaterThan。 Filter属性具有一个名为Empty的特殊属性,对应于在Mongo shell中的早期示例中看到的空的JSON过滤器{}。 它也是FilterDefinition等效于上面的Find示例中的“return true”LINQ语句。
Filter方法,如Eq和Gte,然后需要一个或多个参数。 Eq函数与其他类似的函数(如Gte和Lt)一样,需要一个字段选择器,形式为LINQ表达式,然后是过滤器值。 上面的例子选择了一个名为“自治市镇”的字段,我们要对值“布鲁克林”过滤这个字段。
我们来看看一个使用FilterDefinition解决方案的逻辑AND运算符的例子:
|
1
2
3
4
5
6
|
ModelContext modelContext = ModelContext.Create(new ConfigFileConfigurationRepository(), new AppConfigConnectionStringRepository());var boroughFilter = Builders<RestaurantDb>.Filter.Eq(r => r.Borough, "Brooklyn");var cuisineFilter = Builders<RestaurantDb>.Filter.Eq(r => r.Cuisine, "Delicatessen");var cuisineAndBoroughFilter = boroughFilter & cuisineFilter;var firstRes = modelContext.Restaurants.Find(cuisineAndBoroughFilter).First();Console.WriteLine(firstRes); |
我们想在布鲁克林找到第一间设有“熟食店”的餐厅。 “&”运算符是链条AND条件的简短符号。 这是一个替代解决方案:
|
1
|
var cuisineAndBoroughFilterAlternative = Builders<RestaurantDb>.Filter.And(boroughFilter, cuisineFilter); |
And函数接受带有任意数量的过滤器定义的集合或参数数组,并将它们与AND结合在一起。 作为旁注,您可能会猜到有一个Or函数接受相同的过滤器定义参数,并将它们与逻辑OR链接在一起。 短的符号是单个管道字符“|”。
以下是一个例子:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
{ "MongoDbId": "56edc2ff03a1cd840734dbb1", "Address": { "BuildingNr": "7114", "Coordinates": [ -73.9068506, 40.6199034 ], "Street": "Avenue U", "ZipCode": "11234" }, "Borough": "Brooklyn", "Cuisine": "Delicatessen", "Grades": [ { "InsertedUtc": "2014-05-29T00:00:00Z", "Grade": "A", "Score": 10 }, { "InsertedUtc": "2014-01-14T00:00:00Z", "Grade": "A", "Score": 10 }, { "InsertedUtc": "2013-08-03T00:00:00Z", "Grade": "A", "Score": 8 }, { "InsertedUtc": "2012-07-18T00:00:00Z", "Grade": "A", "Score": 10 }, { "InsertedUtc": "2012-03-09T00:00:00Z", "Grade": "A", "Score": 13 }, { "InsertedUtc": "2011-10-14T00:00:00Z", "Grade": "A", "Score": 9 } ], "Name": "Wilken'S Fine Food", "Id": 40356483} |
这是LINQ风格的解决方案:
|
1
|
var firstResWithLinq = modelContext.Restaurants.Find(r => r.Borough == "Brooklyn" && r.Cuisine == "Delicatessen").FirstOrDefault(); |
让我们看看更复杂的一些:找到第一家餐厅,其等级阵列包括A,B和C级,即每个餐厅中至少有一个。 在这种情况下,我们需要深入对象图。 Filter属性具有一个All函数,它为数组字段构建$ all过滤器,但在这种情况下我们不能使用它。 如果等级数组只是一个简单的字符串数组,如“grade:[”A“,”B“]”,All方法将会有所帮助。 我们需要在这里更深一层。
该解决方案以与AND相关联的三个ElemMatch函数的形式。 ElemMatch函数接受集合字段,然后接收集合子属性上的过滤器,如下所示:
|
1
2
3
4
5
6
|
var arrayFilterGradeA = Builders<RestaurantDb>.Filter.ElemMatch(r => r.Grades, g => g.Grade == "A");var arrayFilterGradeB = Builders<RestaurantDb>.Filter.ElemMatch(r => r.Grades, g => g.Grade == "B");var arrayFilterGradeC = Builders<RestaurantDb>.Filter.ElemMatch(r => r.Grades, g => g.Grade == "C");var arrayFilterWithAllGrades = arrayFilterGradeA & arrayFilterGradeB & arrayFilterGradeC;var firstResWithAllGrades = modelContext.Restaurants.Find(arrayFilterWithAllGrades).FirstOrDefault();Console.WriteLine(firstResWithAllGrades); |
这是一个与过滤器匹配的餐厅:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
{ "MongoDbId": "56edc2ff03a1cd840734dbb5", "Address": { "BuildingNr": "1269", "Coordinates": [ -73.871194, 40.6730975 ], "Street": "Sutter Avenue", "ZipCode": "11208" }, "Borough": "Brooklyn", "Cuisine": "Chinese", "Grades": [ { "InsertedUtc": "2014-09-16T00:00:00Z", "Grade": "B", "Score": 21 }, { "InsertedUtc": "2013-08-28T00:00:00Z", "Grade": "A", "Score": 7 }, { "InsertedUtc": "2013-04-02T00:00:00Z", "Grade": "C", "Score": 56 }, { "InsertedUtc": "2012-08-15T00:00:00Z", "Grade": "B", "Score": 27 }, { "InsertedUtc": "2012-03-28T00:00:00Z", "Grade": "B", "Score": 27 } ], "Name": "May May Kitchen", "Id": 40358429} |
该示例表明,有时我们需要在驱动程序中创建我们的查询,以应用我们想要的,但最终我们可以找到相当于Mongo shell中写入的过滤器。
.Net-Mongodb学习大全网址的更多相关文章
- mongodb学习相关网址
1.MongoDB官网 https://www.mongodb.org 2.MongoDB教程 http://www.yiibai.com/mongodb 3.MongoDB教程http://www. ...
- Mongodb学习笔记一(Mongodb环境配置)
Mongodb学习 说明: MongoDB由databases组成,database由collections组成,collection由documents组成,document由fileds组成.Mo ...
- MongoDB学习(1)--安装,基本curd操作
知识点: 1-MongoDB 安装,启动和卸载 2-基本概念 3-基本的增删改查操作(CURD) 来回顾总结一把学习的mongodb,如果有javascript基础,学习"芒果DB" ...
- MongoDB学习笔记系列
回到占占推荐博客索引 该来的总会来的,Ef,Redis,MVC甚至Sqlserver都有了自己的系列,MongoDB没有理由不去整理一下,这个系列都是平时在项目开发时总结出来的,希望可以为各位一些帮助 ...
- MongoDB学习笔记—Linux下搭建MongoDB环境
1.MongoDB简单说明 a MongoDB是由C++语言编写的一个基于分布式文件存储的开源数据库系统,它的目的在于为WEB应用提供可扩展的高性能数据存储解决方案. b MongoDB是一个介于关系 ...
- MongoDB学习记录
一.操作符 "$lt" :"<""$lte" :"<=""$gt" :"> ...
- PHP操作MongoDB学习笔记
<?php/*** PHP操作MongoDB学习笔记*///*************************//** 连接MongoDB数据库 **////*************** ...
- MongoDB学习:(二)MongoDB简单使用
MongoDB学习:(二)MongoDB简单使用 MongoDB使用: 执行mongodb的操作之前,我们需要运行命令,来进入操作命令界面 >mongo 提示该错误,说明我们系统缺少一个补丁,该 ...
- MongoDB学习:(一)MongoDB安装
MongoDB学习:(一)MongoDB安装 MongoDB介绍: 直接百科了: MongoDB安装: 1:下载安装: MongoDB安装:https://www.mongodb.com/do ...
随机推荐
- bubble chat listview
最近在iOS中用到bubble chat listview,找了个比较有名气的lib(MessagesTableViewController)=>https://github.com/jesse ...
- 邁向IT專家成功之路的三十則鐵律 鐵律二十五:IT人屈辱之道-十倍奉還
現代人普遍火氣都很大,與人爭論時只要有一點點感到屈辱,便會開始大聲反擊,甚至於暴力相向.至於企業中的人事相鬥,則是典型的來個明爭暗鬥,直到成為老闆眼中的紅人,在逐漸掌握了權力之後再來個內部大清洗,不久 ...
- nodeJS一些事儿
node-webkit:开发桌面+WEB混合型应用的神器[大漠穷秋] 展望未来 其实这条路老早就有人在走 网上有很多人在争论,未来究竟是原生的应用会胜出,还是WEB APP会胜出,实际上这两者并不是你 ...
- iOS -- SKEmitterNode类
SKEmitterNode类 继承自 SKNode:UIResponder:NSObject 符合 NSCoding(SKNode)NSCopying(SKNode)NSObject(NSObje ...
- activiti自己定义流程之整合(二):使用angular js整合ueditor创建表单
基础环境搭建完成,接下来就该正式着手代码编写了,在说代码之前.我认为有必要先说明一下activit自己定义流程的操作. 抛开自己定义的表单不谈.通过之前的了解,我们知道一个新的流程開始.是在启动流程实 ...
- ccs 中的定位
一.相对定位 position:relative; 作用: 相对定位 一般加给定位元素父级 特点: (1)不脱离文档流: (2)不改变元素类型: (3)参照物是元素本身: 二.绝对定位 posi ...
- Spin.js-CSS动画进度载入器
spin.js是一款很easy的CSS载入器,他是一款使用了VML(Vector Makeup Language)的CSS动画效果. spin.js的特性 他有着很强大的适应性.有着下面几个特性: 1 ...
- Cocos2d-x学习笔记(18)(TestCpp源代码分析-2)
本章主要讲controller.h/cpp文件的分析,该文件主要用于演示样例场景管理类TestController,用于显示全部演示样例的菜单. //controller.cpp #include & ...
- odoo高级物流应用:跨厂区生产
业务情景 半成品在分厂生产,然后再在总厂组装 半成品所需的原材料存储在分厂的仓库 总厂需要的原材料储存在总厂的仓库 公用的原材料储存在总厂的仓库 解决方案 使用仓库间的供应 设置合适的Rout ...
- kubernetes集群管理命令(二)
系列目录 上一节我们介绍了一些基本的命令,这一节我们介绍一些更为复杂的命令. pod排序 使用kubectl get pod获取pod资源默认是以名称排序的,有些时候我们可能希望按其它顺序排序.比如说 ...