初识MongoDB和.NET Core入门

本文涉及的产品
云数据库 MongoDB,通用型 2核4GB
简介: 初识MongoDB和.NET Core入门

浅入 MongoDB


MonogoDB 是什么


MongoDB 是 NoSQL 型数据库,主要特征是存储结构化数据,MongoDB 是基于分布式文件存储的开源数据库系统。


结构化数据

以往我们使用 Mysql、SqlServer 等数据库,数据都是一条条的。MongoDB 的结构化数据正是区别于这种列-行式的数据。


结构化数据具有层级关系:

例如:

{
     name: "MongoDB",
     type: "database",
     count: 1,
     info: {
         x: 203,
         y: 102
     }
}

微信图片_20220504115515.png

MongoDB 与关系型数据库


由于 MongoDB 中,没有表、行、列,因此初学 MongoDB 时可能会有困扰,这里给出一些 MongoDB 与 普通SQL数据库对应的术语。


SQL术语/概念 MongoDB术语/概念 解释/说明
database database 数据库
table collection 数据库表/集合
row document 数据记录行/文档
column field 数据字段/域
index index 索引
table joins 非关系型数据库,表与表之间没关系
primary key primary key 主键,MongoDB自动将_id字段设置为主键

资料来源:https://www.runoob.com/mongodb/mongodb-databases-documents-collections.html


MongoDB 入门命令


使用 mongo 进入 MongoDB shell 后,可使用命令(相当于SQL)执行操作。

注: MongoDB 中,有一个自动的 _id 字段,此字段 MongoDB 自动设置为主键并自动生成值。


显示所有数据库(包含系统数据库):

show dbs


当前正在操作的数据库或集合:

db


连接到指定数据库:

use {数据库名称}


显示所有集合:

show collections
# 或
show tables


查看集合中的所有文档:

# MyCollection 是集合名称
db.getCollection("MyCollection").find()
db.getCollection("MyCollection").find().limit(1000).skip(0)


可能你不信,笔者百度了很久,第一页没找到一篇合适的友好的 "mongoDB 查看集合中的所有文档",特别是 CSDN 的垃圾文真的多。建议别瞎折腾了,去下一个 Navicat Premium,操作的时候,底部会提示所用的命令。

网络异常,图片无法展示
|

另外 MongoDB 有很多实用工具:https://docs.mongodb.com/tools/


文档


MongoDB 中的文档(Document)即关系型数据库中的一条记录(row)、一行数据。

但, MongoDB 中,一个集合(Collection-Table)中,是不需要具有相同字段的。例如:

A 文档:

{
     name: "MongoDB",
     type: "database",
     count: 1,
     info: {
         x: 203,
         y: 102
     }
}


B 文档:

{
     name: "MongoDB",
     typeName: "database",
     dataCount: 1,
     dataInfo: {
         m: 203,
         n: 102
     }
}


.NET Core 示例


我们从一个基础模板开始。

创建一个控制台程序,打开 Nuget 搜索并安装 MongoDB.Driver

var client = new MongoClient("mongodb://{MongoDB}:27017");
            IMongoDatabase database = client.GetDatabase("Test");


集合


可以通过 CreateCollection()CreateCollectionAsync() 创建一个集合,跟普通数据库不同的是,创建集合时是不需要指定结构的,只需要指定名称即可:

await database.CreateCollectionAsync("Test");


获取集合

GetCollection() 函数可以让我们获取到集合,如果集合不存在,则会自动创建。


IMongoCollection<TDocument> GetCollection<TDocument>()

由于同一个集合可以有不同字段和字段类型的文档,因此几个文档如果有所差别,是很难统一起来的,例如:

微信图片_20220504115557.png


(N/A) 代表此文档没有这个字段;如果一个文档有 10 个字段,另一个文档有 8 个字段,但是两者的字段完全不同时,要合并起来来,就有 18 个字段了。很明显,不应该汇集在一起,而是应该使用强类型对其 ”归档“ 。


创建两个类,分别为 Test1,Test2,其内容如下:

public class Test1
    {
        public string Name { get; set; }
    }
    public class Test2
    {
        public string DataType { get; set; }
    }


以两种文档类型获取集合:

var collection1 = database.GetCollection<Test1>("Test");
            var collection2 = database.GetCollection<Test2>("Test");


这个获取集合的意思是,获取此集合中这类格式的文档的操作能力。

往集合中插入数据:

collection1.InsertOne(new Test1 { Name = "Test1" });
            collection2.InsertOne(new Test2 { DataType = "Test2" });
      // await collection.InsertOneAsync(object);


启动,查看结果。

微信图片_20220504115757.png

InsertMany() 可以插入批量数据:

Test1[] datas = new Test1[]
            {
                new Test1 { Name = "Test1" }
            };
            collection1.InsertMany(datas);


统计数量


获取集合中所有的文档数:

collection1.CountDocuments(new BsonDocument())
// await collection1.CountDocumentsAsync(new BsonDocument());


任意一个文档集合对象,使用 CountDocuments(new BsonDocument()) 都是获得此集合的所有文档数,而不是此类型的文档数。例如:

var collection1 = database.GetCollection<Test1>("Test");
            collection1.CountDocuments(new BsonDocument())


获取的并不是 Test1 类型的文档数量,而是整个集合所有文档的数量。

原因是,CountDocuments() 是一个过滤器函数,可以使用指定条件来筛选符合条件的文档的数量。指定条件后面会介绍。


查询


MongoDB 的查询并不像 LInq 中的表达式,基础了 IEnumerableIEnumerable<T> 接口,因此驱动没有 WhereSelect 这种表达式的查询方法。


Find() 函数是查询函数,里面可以添加丰富的表达式,来筛选文档,当数据加载到本地内存后,即可使用丰富的表达式。


BsonDocument 是一个类型,代表了要查询的文档筛选条件,如果 BsonDocument 对象没有添加任何属性,则代码没有筛选参数,则默认所有文档都符号条件。


我们把 Test1 和 Test2 类型,都加上一个属性:

public ObjectId _id { get; set; }

不然会报格式化错误:System.FormatException


如何序列化文档

document 是文档对象, JsonSerializer 是 System.Text.Json 的静态类。

Console.WriteLine(JsonSerializer.Serialize(document));

查询第一条记录

var document = collection1.Find(new BsonDocument()).FirstOrDefault();


不加条件可能导致的问题


以下代码会导致程序报错:

var documents = await collection1.Find(new BsonDocument()).ToListAsync();
            foreach(var item in documents)
            {
                Console.WriteLine(JsonSerializer.Serialize(item));
            }


因为 collection1 是标记为 Test1 的文档集合;但是 .Find(new BsonDocument()) 是查询集合中的所有文档,因此获取到 Test2。

但是 Test2 是不能转为 Test1 的,因此,会导致程序报错。


查看所有文档

var documents = collection1.Find(new BsonDocument()).ToList();
var documents = await collection1.Find(new BsonDocument()).ToListAsync();

前面已经说过,如果集合中存在其它格式的文档,获取全部文档时,因为 Test2 跟 Test1 没任何关系,会导致 MongoDB.Driver 报错。


如果文档数量比较大,要使用异步的 ForEachAsync() 查询,其原理是 回调。

List<Test1> tests = new List<Test1>();
            Action<Test1> action = item =>
            {
                tests.Add(item);
                Console.WriteLine(JsonSerializer.Serialize(item));
            };
            await collection1.Find(new BsonDocument()).ForEachAsync(action);


查询结束

使用 Find() 以及后续函数查询后,要结束查询(延迟加载),可以使用 ToCursor() 函数结束,程序会立即开始查询并将数据返回内存。


转换查询

使用 ToEnumerable() 可以使用 Linq 来查询文档。

var list = collection1.Find(new BsonDocument()).ToCursor().ToEnumerable();


过滤器

前面我们查询的时候都使用 .Find(new BsonDocument())BsonDocument 是过滤器对象,里面存储了过滤的规则,但是我们不能直接设置 new BsonDocument() 中的属性,而是使用构建器FilterDefinitionBuilder对象,而此对象可以通过 MongoDB.Driver.Builders<TDocument>.Filter 创建 。


假设有以下数据集(文档):

5f8bdf88e63d14cb5f01dd85  小明  19
5f8bdf88e63d14cb5f01dd86  小红  20
5f8bdf88e63d14cb5f01dd87  小张  16
5f8bdf88e63d14cb5f01dd88  小小  17
# -----插入数据的代码-----
    public class Test
    {
        public ObjectId _id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }
            var datas = new Test[]
            {
                new Test{ Name="小明",Age=19},
                new Test{ Name="小红",Age=20},
                new Test{ Name="小张",Age=16},
                new Test{ Name="小小",Age=17}
            };
            collection.InsertMany(datas);


使用构建器:

FilterDefinition<Test> filter = Builders<Test>.Filter


查询 Age 大于 18 的文档:

FilterDefinition<Test> filter = filterBuilder.Where(item => item.Age >= 18);


获取结果:

Test[] documents = collection.Find(filter).ToEnumerable<Test>().ToArray();

过滤器还有 Gt()In()Lte() 等非 Linq 的函数,需要查看文档学习。


Builders<TDocument>


Builders<TDocument> 除了能够生成过滤构建器,还有其它几种构建器:

// 条件过滤
        public static FilterDefinitionBuilder<TDocument> Filter { get; }
    // 索引过滤
        public static IndexKeysDefinitionBuilder<TDocument> IndexKeys { get; }
    // 映射器,相当于使用 Linq 的 .Select() 查询自己只需要的字段
        public static ProjectionDefinitionBuilder<TDocument> Projection { get; }
    // 排序,创建排序规则,如工具年龄排序
        public static SortDefinitionBuilder<TDocument> Sort { get; }
    // 更新,更新某些字段的值等
        public static UpdateDefinitionBuilder<TDocument> Update { get; }


详细请参考 https://mongodb.github.io/mongo-csharp-driver/2.10/reference/driver/definitions/#projections


名称映射


由于 MongoDB 区分字段的大小写,文档的字段一般使用驼峰命名法,首字母小写,而 C# 字段属性首字母是 大小开头的,因此需要不同名称对应起来。

可以使用 BsonElement 特性来设置映射的名称。


class Person
{
    [BsonElement("fn")]
    public string FirstName { get; set; }
    [BsonElement("ln")]
    public string LastName { get; set; }
}


以上就是 MongoDB 的初入门知识,但是使用了 MongoDB 有什么好处?可以参考阿里云的这篇文章:https://developer.aliyun.com/article/64352


整理场景如下:

  • 存储应用程序日志。日志结构化,查找方便,可以导出其它格式和二次利用。
  • 增加字段不需要改动表结构,灵活变更。
  • 支持 json 格式导入;类似 json 的数据结构;能够很容易还原对象的属性,一次性存储数据;如果使用传统数据库,则需要建立多个表并设置主键外界关系。
  • 集群。分布式集群海量数据,容易拓展;故障转移保证服务可用;
  • 解决分布式文件存储需求。
  • 索引方式灵活。
  • ... ...
相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
1月前
|
消息中间件 前端开发 小程序
一个基于.NET Core构建的简单、跨平台、模块化的商城系统
今天大姚给大家分享一个基于.NET Core构建的简单、跨平台、模块化、完全开源免费(MIT License)的商城系统:Module Shop。
|
1月前
|
算法 C# 数据库
【干货】一份10万字免费的C#/.NET/.NET Core面试宝典
C#/.NET/.NET Core相关技术常见面试题汇总,不仅仅为了面试而学习,更多的是查漏补缺、扩充知识面和大家共同学习进步。该知识库主要由自己平时学习实践总结、网上优秀文章资料收集(这一部分会标注来源)和社区小伙伴提供三部分组成。该份基础面试宝典完全免费,发布两年来收获了广大.NET小伙伴的好评,我会持续更新和改进,欢迎关注我的公众号【追逐时光者】第一时间获取最新更新的面试题内容。
|
1月前
|
数据可视化 网络协议 C#
C#/.NET/.NET Core优秀项目和框架2024年3月简报
公众号每月定期推广和分享的C#/.NET/.NET Core优秀项目和框架(每周至少会推荐两个优秀的项目和框架当然节假日除外),公众号推文中有项目和框架的介绍、功能特点、使用方式以及部分功能截图等(打不开或者打开GitHub很慢的同学可以优先查看公众号推文,文末一定会附带项目和框架源码地址)。注意:排名不分先后,都是十分优秀的开源项目和框架,每周定期更新分享(欢迎关注公众号:追逐时光者,第一时间获取每周精选分享资讯🔔)。
|
2月前
|
存储 NoSQL Unix
.NET生成MongoDB中的主键ObjectId
.NET生成MongoDB中的主键ObjectId
.NET生成MongoDB中的主键ObjectId
|
12天前
|
开发框架 .NET 中间件
七天.NET 8操作SQLite入门到实战 - (2)第七天Blazor班级管理页面编写和接口对接
七天.NET 8操作SQLite入门到实战 - (2)第七天Blazor班级管理页面编写和接口对接
|
2天前
|
存储 NoSQL MongoDB
Mongodb 入门
Mongodb 入门
5 0
|
3天前
|
存储 NoSQL MongoDB
【MongoDB 专栏】MongoDB 入门指南:从零开始学习
【5月更文挑战第10天】本文介绍了MongoDB,一个流行的NoSQL数据库,以其灵活的数据模型和高性能著称。内容包括MongoDB的基础知识、安装配置、文档数据模型、数据库操作(如创建、查询、更新和删除)、索引创建、数据备份恢复及性能优化策略。此外,还探讨了MongoDB在社交网络、电子商务等领域的应用。对于初学者,本文提供了从零开始学习MongoDB的入门指导。
【MongoDB 专栏】MongoDB 入门指南:从零开始学习
|
18天前
|
开发框架 前端开发 JavaScript
JavaScript云LIS系统源码ASP.NET CORE 3.1 MVC + SQLserver + Redis医院实验室信息系统源码 医院云LIS系统源码
实验室信息系统(Laboratory Information System,缩写LIS)是一类用来处理实验室过程信息的软件,云LIS系统围绕临床,云LIS系统将与云HIS系统建立起高度的业务整合,以体现“以病人为中心”的设计理念,优化就诊流程,方便患者就医。
22 0
|
1月前
|
Linux API iOS开发
.net core 优势
.NET Core 的优势:跨平台兼容(Windows, macOS, Linux)及容器支持,高性能,支持并行版本控制,丰富的新增API,以及开源。
27 4
|
1月前
|
开发框架 人工智能 .NET
C#/.NET/.NET Core拾遗补漏合集(持续更新)
在这个快速发展的技术世界中,时常会有一些重要的知识点、信息或细节被忽略或遗漏。《C#/.NET/.NET Core拾遗补漏》专栏我们将探讨一些可能被忽略或遗漏的重要知识点、信息或细节,以帮助大家更全面地了解这些技术栈的特性和发展方向。