一. MongoDB介绍 

MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。

在高负载的情况下,添加更多的节点,可以保证服务器性能。

MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。

MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。

 

MongoDB学习(ASP.NET Core 3.1)_MongoDB学习

二. MongoDB基本操作

1.MongoDB(创建/删除)数据库

1.创建,如果数据库不存在,则创建数据库,不然就切换到这个数据库。

use DATABASE_NAME

2.删除,先use切换到数据库里,执行删除

use DATABASE_NAME
db.dropDatabase()

 

2.创建集合(createCollection)

在关系型数据库中叫表,在MongoDB中叫集合。

db.createCollection(name, options)

 

下列关于options属性设置解释:

字段类型描述
cappedbool(可选)如果为 true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。 当该值为 true 时,必须指定 size 参数。
maxint(可选)指定固定集合中包含文档的最大数量。
sizeint(可选)为固定集合指定一个最大值,即字节数。 如果 capped 为 true,也需要指定该字段。

3.删除集合( drop() )

MongoDB中使用drop()方法来删除集合

use DATABASE_NAME
db.collection.drop()

 

4.插入文档( insert() )

MongoDB中使用insert()或save()方法向集合插入文档:

MongoDB提供了保存数据的方法一共有三个:
    1. db.collection.insertOne()2. db.collection.insertMany()3. db.collection.insert()

 

 

① db.collection.insertOne()例子:

#只能插入 单个 集合
db.users.insertOne(
   {
      name: "sue",
      age: 19,
      status: "P"
   }
)

 

② db.collection.insertMany()例子:

#将 多个 文档对象插入到一个集合,
db.users.insertMany(
   [
     { name: "bob", age: 42, status: "A", },
     { name: "ahn", age: 22, status: "A", },
     { name: "xi", age: 34, status: "D", }
   ]
)

 

③ db.collection.insert()例子:

## 可插入一个 or 多个对象 到集合中//插入单个对象db.users.insert(
   {
      name: "sue",
      age: 19,
      status: "P"
   }
)//插入数组db.users.insert(
   [
     { name: "bob", age: 42, status: "A", },
     { name: "ahn", age: 22, status: "A", },
     { name: "xi", age: 34, status: "D", }
   ]
)

 

5.更新文档( update() )

update() 方法用于更新已存在的文档。语法格式如下:

db.collection.update(   <query>,   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
)

 

参数说明:

  • query : update的查询条件,类似sql update查询内where后面的。

  • update : update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的

  • upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。

  • multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。

  • writeConcern :可选,抛出异常的级别。

    实例如下:

use MyMongoDB
db.Province.update({'_id':ObjectId('6072ec60c7760000810002d6')}, 
{$set:{'ProvinceName':'广元'}},
{multi:true})

 

6.删除文档( remove() )

remove()方法的基本语法格式如下:

db.collection.remove(   <query>,   <justOne>)

 

justOne : (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档。

实例:

use MyMongoDB
db.Province.remove({'_id':ObjectId('6072ec60c7760000810002d6')}, 1)

 

7.查询文档( find() )

MongoDB 查询数据的语法格式如下:

db.collection.find(query, projection)

 

MongoDB中and条件

db.collection.find({key1:value1 , key2:value2}).pretty()

 

MongoDB中or条件

db.collection.find(
 {
$or:[
    {key1:value1 , key2:value2}
    ]
  }
).pretty()

 

8.MongoDB 条件操作符

MongoDB中条件操作符有:

  • (>) 大于 - $gt

  • (<) 小于 - $lt

  • (>=) 大于等于 - $gte

  • (<= ) 小于等于 - $lte

与sql对比

db.col.find({likes : {$gt : 100}})
#1.(>) 大于 - $gt
Select * from col where likes > 100;

db.col.find({likes : {$lt : 100}})
#2.(<) 小于 - $lt
Select * from col where likes < 100;

db.col.find({likes : {$gte : 100}})
#3.(>=) 大于等于 - $gte
Select * from col where likes >= 100;

db.col.find({likes : {$lte : 100}})
#4.(<= ) 小于等于 - $lte
Select * from col where likes <= 100;

 

9.获取指定区间数据( limit() / skip() )

① limit()获取指定的条数,limit(2)则会返回两条数据

db.COLLECTION_NAME.find().limit(NUMBER)

 

② skip()跳过指定的条数,skip(2)则会跳过两条数据从第三条开始显示

db.COLLECTION_NAME.find().skip(NUMBER)

 

可以通过.limit().skip()来实现分页。

10.MongoDB排序

使用sort()进行排序,通过参数1or-1来指定排序方式,1为升序排列,而-1是用于降序排列

db.COLLECTION_NAME.find().sort({KEY:1})

 

实例( ps:查询结果是先排序了,后进行skip()和limit()操作。sort()→skip()→limit() ):

db.Province.find().limit(6).skip(2).sort({'_id':-1})

 

11.MongoDB索引

索引主要用于提高查询的效率。索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构

注意!!!:每个索引占据一定的存储空间,在进行插入,更新和删除操作时也需要对索引进行操作。所以,如果你很少对集合进行读取操作,建议不使用索引。

 

索引创建createIndex()方法基本语法格式如下所示:

db.collection.createIndex(keys, options)

 

实例:(1为升序创建索引,-1为降序创建索引)

db.col.createIndex({"title":1})
#支持多字段创建索引。
db.col.createIndex({"title":1,"description":-1})

 

options的参数如下: (遇到超大表时,使用background 方式后台创建索引,可以避免阻塞)

MongoDB学习(ASP.NET Core 3.1)_MongoDB学习_02

索引其他操作:

#查看索引集合
db.Province.getIndexes()
#查看集合索引大小
db.Province.totalIndexSize()
#删除集合所有索引
db.Province.dropIndexes()
#删除指定的索引
db.Province.dropIndex("索引名字")

 

12.MongoDB 聚合(计算)

MongoDB 中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。

有点类似 SQL 语句中的 count(*)。

①aggregate() 方法

基本语法格式如下所示:

db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)

 

一般聚合的表达式有:$sum、$avg、$min、$max、$push、$addToSet、$first、$last实例。

db.mycol.aggregate(
    [
        {
        $group : {
        _id : "$by_user", 
        num_tutorial : {$sum : "$likes"}
                    }
        }
    ]
)

MongoDB学习(ASP.NET Core 3.1)_MongoDB学习_03

②聚合管道

1.概念

处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档。

  • 对文档进行过滤,查询出符合条件的文档

  • 对文档进行变换,改变文档的输出形式

    概念图如下:

    MongoDB学习(ASP.NET Core 3.1)_MongoDB学习_04

 

2.常用

常用的操作有:

  • $project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。

    db.TestDb.aggregate({$project:{_id:0,title:1,  newAdd:"$url"  ,by_user:1,}})

     

  • $match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。

    db.TestDb.aggregate({$match:{"likes":{$gte:101}}}) #只显示>=101的数据

     

  • $limit:用来限制MongoDB聚合管道返回的文档数。

    db.TestDb.aggregate([{$sort:{"_id":-1}},{$limit:2}])#限制文档输出,只输出2组数据

     

  • $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。

  • $unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。

    db.TestDb.aggregate([{$match:{"likes":{$gte:10}}},{$unwind:"$title"}])

     

  • $group:将集合中的文档分组,可用于统计结果。

  • $sort:将输入文档排序后输出。

    db.TestDb.aggregate({$sort:{"_id":-1}})#根据_id降序输出

     

  • $geoNear:输出接近某一地理位置的有序文档。

    关于聚合管道还有很多很多...

13.覆盖索引查询

官方的MongoDB的文档中说明,覆盖查询是以下的查询:

  • 所有的查询字段是索引的一部分

  • 所有的查询返回字段在同一个索引中

例如当存在联合索引,且字段包含gender,user_name时:

db.users.ensureIndex({gender:1,user_name:1})

 

就会覆盖以下查询:

db.users.find({gender:"M"},{user_name:1,_id:0})
#or
db.users.find({gender:"M"})

 

当不排除id时(id:1),则不会覆盖,因为超出了联合索引的覆盖范围:

db.users.find({gender:"M"},{user_name:1})

 

14.MongoDB 自动增长

。。

三. asp.net core for MongoDB

1.安装MongoDB.Driver包

MongoDB学习(ASP.NET Core 3.1)_MongoDB学习_05

2.添加支持类

为了提高代码的使用率。这里采用MongoDBHelp帮助类的模式。底层连接部分是一样的,唯独不一样的是依赖注入所支持的模型类不一样。

①创建基础类BaseModel.cs

这个类主要是为了让BaseService能实现泛型

    public class BaseModel
    {
        [BsonId]        //标记主键[BsonRepresentation(BsonType.ObjectId)]     //参数类型  , 无需赋值public string Id { get; set; }

        [BsonElement(nameof(CreateDateTime))]   //指明数据库中字段名为CreateDateTimepublic DateTime CreateDateTime { get; set; }//[BsonElement(nameof(IsDelete))]public bool IsDelete { get; set; }public BaseModel()
        {
            CreateDateTime = DateTime.Now;
            IsDelete = false;
        }
    }

 

②创建数据模型类Province.cs

乱写个实体类来做测试。

    public class Province:BaseModel//继承基础类    {
        [BsonId]public ObjectId ProvinceID { get; set; }public string ProvinceName { get; set; }
    }

 

③创建MongoDB连接及核心业务

BaseService.cs类主要负责数据库连接和执行CURD等基本操作。

    public class BaseService<T>where T:BaseModel
    {private readonly IMongoCollection<T> _collection;   //数据表操作对象public BaseService(IConfiguration config, string tableName)
        {var client = new MongoClient(config.GetConnectionString("MongoDBDemo"));    //获取链接字符串var database = client.GetDatabase(config.GetSection("MongoDBSetting:DBName").Value);   //数据库名 (不存在自动创建)//获取对特定数据表集合中的数据的访问_collection = database.GetCollection<T>(tableName);     // (不存在自动创建)        }/// <summary>/// 获取所有/// </summary>/// <returns></returns>public List<T> Get()
        {return _collection.Find(T => true).ToList();
        }/// <summary>/// 获取单个/// </summary>/// <param name="id"></param>/// <returns></returns>public T Get(string id)
        {return _collection.Find<T>(T => T.Id == id).FirstOrDefault();
        }/// <summary>/// 创建/// </summary>/// <param name="T"></param>/// <returns></returns>public T Create(T T)
        {
            _collection.InsertOne(T);return T;
        }/// <summary>/// 更新/// </summary>/// <param name="id"></param>/// <param name="TIn"></param>public void Update(string id, T TIn)
        {
            _collection.ReplaceOne(T => T.Id == id, TIn);
        }/// <summary>/// 删除/// </summary>/// <param name="TIn"></param>public void Remove(T TIn)
        {
            _collection.DeleteOne(T => T.Id == TIn.Id);
        }/// <summary>/// 根据id删除/// </summary>/// <param name="id"></param>public void Remove(string id)
        {
            _collection.DeleteOne(T => T.Id == id);
        }
    }

 

④使用BaseService

通过BaseService我们就可以直接连接到MongoDB数据库中了,但为了更好的适配其他不同类型的实体类,我们只是单独封装了BaseService这个类,方便其他实体共同调用。例如为Province提供连接服务

创建ProvinceService:

    public class ProvinceService : BaseService<Province>{public ProvinceService(IConfiguration config) : base(config, nameof(Province)) { }
    }

 

这样我们就将连接类和实体类绑定在一起了,接下来我们进行依赖注入方便调用

⑤依赖注入

        public void ConfigureServices(IServiceCollection services)
        {//注入Province文档依赖services.AddScoped<ProvinceService>();

            services.AddControllersWithViews();
        }

 

这样,我们就可以直接从容器中运行了

⑥在控制器中使用

 private readonly DbContext _dbContext; public HomeController(ILogger<HomeController<T>> logger,ICount count,DbContext dbContext)
        {
            _logger = logger;
            _dbContext = dbContext;

        }

 

3.注意

当你想把连接字符串改为本机ip的时候就会发现连接不成功的情况,这是因为默认的MongoDB的连接是绑定了127.0.0.1自己本身,所以不支持其他ip。

MongoDB学习(ASP.NET Core 3.1)_MongoDB学习_06

把127.0.0.1改为即可0.0.0.0