• MongoDB 入门


    1 MongoDb 简介

    MongoDB是为互联网而生的数据库,是文档数据库。

    1.1 优点:

    1. Schema-less,不需要预先定义表结构,同一个“表”中可以保存多个格式的数据;
    2. 数据支持嵌套,数据以json格式存储;
    3. 允许使用JavaScript写服务端脚本,类似于存储过程;
    4. 支持Map/Reduce;
    5. MongoDB支持地理位置索引,可以直接用于位置距离计算和查询,实现“附近的人”、
      “滴滴打车接单”等很容易;

    1.2 缺点:

    1. Mongodb没有“数据一致性检查”、“事务”等,不适合存储对数据事务要求高(比如金融)的数据;只适合放非关键性数据(比如日志或者缓存)。
    2. 关联查询很弱,不适合做报表查询

    2 MongoDB 下载

    MongoDB 提供了可用于 32 位和 64 位系统的预编译二进制包,你可以从MongoDB官网下载安装,MongoDB 预编译二进制包下载地址:https://www.mongodb.com/download-center#community

    2.1 创建数据目录

    MongoDB将数据目录存储在 db 目录下。但是这个数据目录不会主动创建,我们在安装完成后需要创建它。请注意,数据目录应该放在根目录下((如: C: 或者 D: 等 )。

    在本教程中,我们已经在 C 盘安装了 mongodb,现在让我们创建一个 data 的目录然后在 data 目录里创建 db 目录。

    http://www.runoob.com/mongodb/mongodb-window-install.html

    2.2 把MongoDB安装成windows服务的方法:

    1) 创建一个配置文件mongod.cfg,在C:Program FilesMongoDBServer4.0in下,内容是:

    systemLog: 
        destination: file 
        path:D:Mongodblogmongod.log 
    storage: 
        dbPath: D:Mongodbdb 
    

    把配置文件中的文件夹创建起来。
    2) 注册成系统服务:

    mongod --config "C:Program FilesMongoDBServer4.0inmongod.cfg" –install
    

    3) 启动服务

    2.3 windows安装方法 https://docs.mongodb.com/master/tutorial/install-mongodb-on-windows/

    3 GUI客户端

    Robo 3T(免费) https://robomongo.org/download

    NoSQLBooster for MongoDB(收费) https://www.nosqlbooster.com/home

    4 .NET操作 MongoDB

    安装.Net驱动:Install-Package MongoDB.Driver
    https://docs.mongodb.com/ecosystem/drivers/csharp/(.NET驱动文档)

    4.1 插入

    4.1.1 类插入

    			MongoClient client = new MongoClient("mongodb://localhost");
                IMongoDatabase database = client.GetDatabase("TestDb1");//相当于数据库 
                IMongoCollection<Person> collection = database.GetCollection<Person>("Persons");//大致相当于“表” 
    
                Person p1 = new Person();
                p1.Id = 2;
                p1.Name = "sanwa";
                p1.Age = 22;
                collection.InsertOne(p1);//也支持异步方法,后面建议都用异步的!习惯成自然!
    

    MongoDB里面:
    (1)新插入的数据,MongoDB会自动创建“数据库”以及Collection(约等于“表”)。
    (2)MongoDB默认用id做主键,因此不用显式指定id是主键。Id 对应 _id
    (3)MongoDB中没有内置“自增字段”,可以把Id声明为ObjectId类型(using MongoDB.Bson)这样插入以后就自动给字段赋值。

    public ObjectId Id { get; set; }
    

    再重新插入一次。

    4.1.2 Json插入

                MongoClient client = new MongoClient("mongodb://localhost");
                IMongoDatabase database = client.GetDatabase("TestDb1");//相当于数据库 
                IMongoCollection<BsonDocument> dogs = database.GetCollection<BsonDocument>("Dogs");
                string json = "{id:10,Age:25,Name:'superman',gender:true}";
                BsonDocument p2 = BsonDocument.Parse(json);
                dogs.InsertOne(p2);
    

    4.2 查询

    4.2.1 一般查询

    重写Person

        public class Person
        {
            public ObjectId Id { get; set; }
            public string Name { get; set; }
            public int Age { get; set; }
    
            public override string ToString()
            {
                return $"{nameof(Id)}: {Id}, {nameof(Name)}: {Name}, {nameof(Age)}: {Age}";
            }
        }
    

    先插入一些数据

    MongoClient client = new MongoClient("mongodb://localhost");
                IMongoDatabase database = client.GetDatabase("TestDb1");
                List<Person> list = new List<Person>();
                list.Add(new Person(){Age = 22,Name = "zhanghua"});
                list.Add(new Person(){Age = 24,Name = "fuqiang"});
                list.Add(new Person(){Age = 31,Name = "jishang"});
                list.Add(new Person(){Age = 42,Name = "liuqiangdon"});
                IMongoCollection<Person> collection = database.GetCollection<Person>("Persons");
                collection.InsertMany(list); //插入list
    

    再查询

            public static async void Query()
            {
                MongoClient client = new MongoClient("mongodb://localhost");
                IMongoDatabase database = client.GetDatabase("TestDb1");//相当于数据库 
    
                IMongoCollection<Person> collection = database.GetCollection<Person>("Persons");
    
                var filter1 = Builders<Person>.Filter.Gt(p => p.Age, 30);//Gt:大于。 
                //多条件,复杂条件使用 linq
                //var filter2 = Builders<Person>.Filter.Where(p => p.Age > 30);//Gt:大于。 
    
                var result =  collection.Find<Person>(filter1);
    
                foreach (var item in result.ToList())
                {
                    Console.WriteLine(item.ToString());
                }
            }
    

    结果

    Id: 5bb79ee398acfb2f544a9521, Name: jishang, Age: 31
    Id: 5bb79ee398acfb2f544a9522, Name: liuqiangdon, Age: 42
    

    4.2.2 大数据量查询

    采用分批次查询。while(foreach...)

            //分批次查询(大数据量)
            public static async void QueryBigSize()
            {
                MongoClient client = new MongoClient("mongodb://localhost");
                IMongoDatabase database = client.GetDatabase("TestDb1");//相当于数据库 
    
                IMongoCollection<Person> collection = database.GetCollection<Person>("Persons");
                var filter1 = Builders<Person>.Filter.Gt(p => p.Age, 30);//Gt:大于。 
                //FindAsync<Person> 返回的是 IAsyncCursor<Person> ,实现的 IDisposable 接口,需要使用using
                //分组查询(按大小): FindOptionsBase.BatchSize
                using (var personsCursor = await collection.FindAsync<Person>(filter1, new FindOptions<Person>(){BatchSize = 1}))
                {
                    while (personsCursor.MoveNext())
                    {
                        IEnumerable<Person> persons = personsCursor.Current;
                        foreach (var p in persons)
                        {
                            Console.WriteLine(p);
                        }
    
                    }
                }
            }
    

    为什么FindAsync不直接返回集合,而是要MoveNext之后返回一个集合呢?因为返回的数据量可能很大,因此MongoDB是分批下载,下载一批之后执行GET_More操作返回下一批。可以通过FindOptions参数的BatchSize设置每一批的大小。

     using (var personsCursor = await collection.FindAsync<Person>(filter1, new FindOptions<Person>(){BatchSize = 1}))
    {
    	...
    }
    

    如果确认返回的数据量 不大,可以var ps = await personsCursor.ToListAsync()(或者ToEnumerable()等)一下子返回所有数据。还有Any、First、FirstOrDefault等以及异步操作。

    需要注意MongoDB中查询区分大小写。

    4.2.3 分页

    使用FindOptions<TDocument, TProjection>

        // 摘要:
        //     查找文档的选项.
        //
        // 类型参数:
        //   TDocument:
        //     文档的类型.
        //
        //   TProjection:
        //     投影的类型 (如果没有投影, 则与 TDocument 相同)。
    FindOptions<TDocument, TProjection> : FindOptionsBase
    {
    public FindOptions();
    //获取或设置要返回的文档数。
    public int? Limit { get; set; }
    public ProjectionDefinition<TDocument, TProjection>
    //获取或设置在返回其余部分之前要跳过的文档数。
    public int? Skip { get; set; }
    //排序
    public SortDefinition<TDocument> Sort { get; set; }
    }
    

    FindAsync 传入参数时,设置 FindOptions

    				using (var personsCursor = await collection.FindAsync<Person>(filter1, 
                    new FindOptions<Person,Person>(){Limit = 2,Skip = 2}))
    				{
    				...
    				}
    

    4.2.4 排序

    findOpt.Sort = Builders<Person>.Sort.Ascending(p => p.Age).Descending(p => p.Name); 
    

    这里可以

    using (var personsCursor = await collection.FindAsync<Person>(filter1, 
                    new FindOptions<Person,Person>()
                    {
                        Limit = 2,Skip = 2,
    					//这里写Sort排序
                        Sort = Builders<Person>.Sort.Ascending(p=>p.Age)
                    }))
                {
    			...
    			}
    

    4.2.5 类型不确定,使用 Bson

    如果用BsonDocument,有一些操作还是比较麻烦的:
    而且不能使用linq了,只能使用Gt、Gte、In、Lt、Lte、Ne、Nin、Near、NearSphere、Or、Where、And、Not。等等。

    IMongoCollection<BsonDocument> persons = database.GetCollection<BsonDocument>("Persons"); 
    var filter1 = Builders<BsonDocument>.Filter.Gt("Age", 5); 
    using (var personsCursor = await persons.FindAsync(filter1)) 
    { 
    	foreach (var p in await personsCursor.ToListAsync()) 
    	{ 
    	MessageBox.Show(p.GetValue("Name").AsString); 
    	} 
    } 
    

    4.3 更新

    用Update机会比较少,如果频繁的用Update可能意味着用错了;也不要想着join、group by,还是场景不对!

    IMongoCollection<Person> teachers = database.GetCollection<Person>("Persons"); 
    var filter = Builders<Person>.Filter.Where(p => p.Age <= 5); 
    var update = Builders<Person>.Update 
     
    .Set(p=>p.Age,8); 
    teachers.UpdateMany(filter, update); 
    

    4.4 删除

    IMongoCollection<Person> teachers = database.GetCollection<Person>("Persons"); 
    var filter = Builders<Person>.Filter.Where(p => p.Age <= 5); 
    teachers.DeleteMany(filter); 
    

    5 应用场景

    日志记录系统;设备监控数据的存储;饿了么外卖骑手接单;存储商品、商家信息;网站评论信息;存储爬虫爬过来的第三方数据;
    但是像订单、金融交易、游戏装备等这些关键信息不要用MongoDB;

  • 相关阅读:
    linux 下载openssl 亲测有效
    在linux文件中 怎么查看文件的行数
    linux 安装mysql 数据库
    bccomp
    javascript之date
    javascript之函数
    JavaScript数据类型之数组
    BOM
    canvas
    javascript数据类型之对象
  • 原文地址:https://www.cnblogs.com/tangge/p/9745740.html
Copyright © 2020-2023  润新知