ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

MongoDB学习(ASP.NET Core 3.1)

2021-04-18 23:33:17  阅读:117  来源: 互联网

标签:Core ASP MongoDB db collection id 文档 public


一. MongoDB介绍 

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

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

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

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

 

img

二. MongoDB基本操作

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

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

use DATABASE_NAME

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

use DATABASE_NAME
db.dropDatabase()

 

2.创建集合(createCollection)

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

db.createCollection(name, options)

 

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

字段类型描述
capped bool (可选)如果为 true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。 当该值为 true 时,必须指定 size 参数。
max int (可选)指定固定集合中包含文档的最大数量。
size int (可选)为固定集合指定一个最大值,即字节数。 如果 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 方式后台创建索引,可以避免阻塞

索引其他操作:

#查看索引集合
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"}
                    }
        }
    ]
)

②聚合管道

1.概念

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

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

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

    概念图如下:

 

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包

2.添加支持类

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

①创建基础类BaseModel.cs

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

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

        [BsonElement(nameof(CreateDateTime))]   //指明数据库中字段名为CreateDateTime
        public 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。image-20210417210121055

把127.0.0.1改为即可0.0.0.0

 

标签:Core,ASP,MongoDB,db,collection,id,文档,public
来源: https://www.cnblogs.com/luomilande/p/14675113.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有