• .net Core MongoDB用法演示


    C#驱动MongoDB的本质是将C#的操作代码转换为mongo shell,驱动的API也比较简单明了,方法名和js shell的方法名基本都保持一致,熟悉mongo shell后学习MongoDB的C#驱动是十分轻松的,直接看几个demo吧。

    0.准备测试数据

    使用js shell添加一些测试数据,如下:

    use myDb
    db.userinfos.insertMany([
       {_id:1, name: "张三", age: 23,level:10, ename: { firstname: "san", lastname: "zhang"}, roles: ["vip","gen" ]},
       {_id:2, name: "李四", age: 24,level:20, ename: { firstname: "si", lastname: "li"}, roles:[ "vip" ]},
       {_id:3, name: "王五", age: 25,level:30, ename: { firstname: "wu", lastname: "wang"}, roles: ["gen","vip" ]},
       {_id:4, name: "赵六", age: 26,level:40, ename: { firstname: "liu", lastname: "zhao"}, roles: ["gen"] },
       {_id:5, name: "田七", age: 27, ename: { firstname: "qi", lastname: "tian"}, address:'北京' },
       {_id:6, name: "周八", age: 28,roles:["gen"], address:'上海' }
    ])

    1 添加(InsertOne,InsertMany)

      安装nuget包(或者执行命令  Install-Package MongoDB.Driver)

     

    然后就可以使用C#操作MongoDB数据库了,看一个添加的demo:

     class Program
        {
            static void Main(string[] args)
            {
                //连接数据库
                var client = new MongoClient("mongodb://root:root@192.168.100.3:27017/");
                //获取database
                var mydb = client.GetDatabase("myDb");
                //获取collection
                var collection = mydb.GetCollection<BsonDocument>("userinfos");
                //待添加的document
                var doc = new BsonDocument{
                    { "_id",7 },
                    { "name", "吴九" },
                    { "age", 29 },
                    { "ename", new BsonDocument
                        {
                            { "firstname", "jiu" },
                            { "lastname", "wu" }
                        }
                    }
                };
                //InsertOne()添加单条docment
                collection.InsertOne(doc);
            }
        }

    执行完成后,查看在NoSQLBooster中查询,看到已经添加成功了:

     

    我们也可以是用 collection.InsertMany(IEnumerable<BsonDocument> docs) 来批量添加docment,这里就不再演示了。

    2  查询(Find,Filter,Sort,Projection)

    1.简单查询(Find、Filter)

     查找name=“吴九"的记录

    var client = new MongoClient("mongodb://root:root@192.168.100.3:27017/");
    //获取database
    var mydb = client.GetDatabase("myDb");
    //获取collection
    var collection = mydb.GetCollection<BsonDocument>("userinfos");
    //Fileter用于过滤,如查询name = 吴九的第一条记录
    var filter = Builders<BsonDocument>.Filter;
    //Find(filter)进行查询
    var doc = collection.Find(filter.Eq("name", "吴九")).FirstOrDefault();
    Console.WriteLine(doc);

    查询结果如下:

     

    如果我们想查询所有的记录,可以设置过滤器为空,代码为: var docs = collection.Find(filter.Empty).ToList(); 

    2.AND查询

    查询年龄大于25且小于28的记录

    //连接数据库
    var client = new MongoClient("mongodb://root:root@192.168.100.3:27017/");
    //获取database
    var mydb = client.GetDatabase("myDb");
    //获取collection
    var collection = mydb.GetCollection<BsonDocument>("userinfos");
    //查询25<age<28的记录
    var filter = Builders<BsonDocument>.Filter;
    var docs = collection.Find(filter.Gt("age", 25) & filter.Lt("age", 28)).ToList();
    docs.ForEach(d => Console.WriteLine(d));

     查询结果如下:

     

    3 OR查询

    查询年龄小于25或年龄大于28的记录

    var client = new MongoClient("mongodb://root:root@192.168.100.3:27017/");
    //获取database
     var mydb = client.GetDatabase("myDb");
    //获取collection
    var collection = mydb.GetCollection<BsonDocument>("userinfos");
    //查询年龄小于25或年龄大于28的记录
    var filter = Builders<BsonDocument>.Filter;
    var docs = collection.Find(filter.Lt("age", 25) | filter.Gt("age", 28)).ToList();
    docs.ForEach(d => Console.WriteLine(d));

    查询结果如下:

     

    4 字段存在(Exists)

    查询包含address字段的所有记录

    //连接数据库
    var client = new MongoClient("mongodb://root:root@192.168.100.3:27017/");
    //获取database
    var mydb = client.GetDatabase("myDb");
    //获取collection
    var collection = mydb.GetCollection<BsonDocument>("userinfos");
    //查询存在address字段的记录
    var filter = Builders<BsonDocument>.Filter;
    var docs = collection.Find(filter.Exists("address")).ToList();
    docs.ForEach(d => Console.WriteLine(d));

    查询结果如下:

     

    5 排序(Sort)

    查询年龄小于26岁的记录,并按年龄倒序排列

    //连接数据库
    var client = new MongoClient("mongodb://root:root@192.168.100.3:27017/");
    //获取database
    var mydb = client.GetDatabase("myDb");
    //获取collection
    var collection = mydb.GetCollection<BsonDocument>("userinfos");
    //查询age<26的记录,按年龄倒序排列
    var filter = Builders<BsonDocument>.Filter;
    var sort = Builders<BsonDocument>.Sort;
    var docs = collection.Find(filter.Lt("age", 26))//过滤
                         .Sort(sort.Descending("age")).ToList();//按age倒序
    docs.ForEach(d => Console.WriteLine(d));

    查询结果如下:

    6 查询指定字段(Projection)

    MongoDB查询会默认返回_id字段,如果要不返回_id字段可以使用Exclude("_id")将其排除。

    //连接数据库
    var client = new MongoClient("mongodb://root:root@192.168.100.3:27017/");
    //获取database
    var mydb = client.GetDatabase("myDb");
    //获取collection
    var collection = mydb.GetCollection<BsonDocument>("userinfos");
    //查询age<26的记录 包含name age 排除 _id
    var project = Builders<BsonDocument>.Projection;
    var filter = Builders<BsonDocument>.Filter;
    var docs = collection.Find(filter.Lt("age", 26))//过滤
                         .Project(project.Include("name")//包含name
                                         .Include("age")//包含age
                                         .Exclude("_id")//不包含_id
                               ).ToList();
    docs.ForEach(d => Console.WriteLine(d));

    查询结果:

     

     3 修改(UpdateOne,UpdateMany)

    1 修改单条记录(UpdateOne)

    修改符合过滤条件的第一条记录,例子:将张三的年龄改成18岁

    //连接数据库
    var client = new MongoClient("mongodb://root:root@192.168.100.3:27017/");
    //获取database
    var mydb = client.GetDatabase("myDb");
    //获取collection
    var collection = mydb.GetCollection<BsonDocument>("userinfos");
    var filter = Builders<BsonDocument>.Filter;
    var update = Builders<BsonDocument>.Update;
    var project = Builders<BsonDocument>.Projection;
    //将张三的年龄改成18
    collection.UpdateOne(filter.Eq("name", "张三"), update.Set("age", 18));
    //查询张三的记录
    var doc = collection.Find(filter.Eq("name", "张三"))
                        .Project(project.Include("age").Include("name"))
                        .FirstOrDefault();
    Console.WriteLine(doc);

    执行结果:

    2 修改多条记录(UpdateMany)

    UpdateMany会修改所有符合过滤条件的记录,例子:将所有年龄小于25的记录标记为young(如果没有mark字段会自动添加)

    //连接数据库
    var client = new MongoClient("mongodb://root:root@192.168.100.3:27017/");
    //获取database
    var mydb = client.GetDatabase("myDb");
    //获取collection
    var collection = mydb.GetCollection<BsonDocument>("userinfos");
    var filter = Builders<BsonDocument>.Filter;
    var update = Builders<BsonDocument>.Update;
    var project = Builders<BsonDocument>.Projection;
    //将张三的年龄改成18
    collection.UpdateOne(filter.Eq("name", "张三"), update.Set("age", 18));
    //查询张三的记录
    var doc = collection.Find(filter.Eq("name", "张三"))
                        .Project(project.Include("age").Include("name"))
                        .FirstOrDefault();
    Console.WriteLine(doc);

    查询结果如下,可以看到age<25的记录的mark字段值为young:

     

    4 删除(DeleteOne和DeleteMany)

    删除操作比较简单,DeleteOne用于删除符合过滤条件的第一条记录,DeleteMany用于删除所有符合过滤条件的记录。

    1 删除单条记录(DeleteOne)

     删除名字为张三的记录

    //连接数据库
    var client = new MongoClient("mongodb://root:root@192.168.100.3:27017/");
    //获取database
    var mydb = client.GetDatabase("myDb");
    //获取collection
    var collection = mydb.GetCollection<BsonDocument>("userinfos");
    var filter = Builders<BsonDocument>.Filter;
    var project = Builders<BsonDocument>.Projection;
    //删除名字为张三的记录
    collection.DeleteOne(filter.Eq("name", "张三"));
    var docs = collection.Find(filter.Empty)
                    .Project(project.Include("age").Include("name").Include("mark"))
                    .ToList();
    docs.ForEach(d => Console.WriteLine(d));

    执行结果如下,我们看到张三的记录已经被删除了:

    2  删除多条记录(DeleteMany)

    删除所有年龄大于25岁的记录

    //连接数据库
    var client = new MongoClient("mongodb://root:root@192.168.100.3:27017/");
    //获取database
    var mydb = client.GetDatabase("myDb");
    //获取collection
    var collection = mydb.GetCollection<BsonDocument>("userinfos");
    var filter = Builders<BsonDocument>.Filter;
    var project = Builders<BsonDocument>.Projection;
    //删除age>25的记录
    DeleteResult result = collection.DeleteMany(filter.Gt("age", 25));
    Console.WriteLine($"一共删除了{result.DeletedCount}条记录");
    var docs = collection.Find(filter.Empty)
                    .Project(project.Include("age").Include("name").Include("mark"))
                    .ToList();
    docs.ForEach(d => Console.WriteLine(d));

    执行结果如下,所有年龄大于25岁的记录都被删除了:

    5 类型映射

    1 简单例子

     有时候我们要让查询的结果映射到我们的实体类中去,实现这个需求也十分简单,mongoDB支持自动映射,直接使用泛型即可,看一个(清空数据db.userinfos.remove({}),从新初始化js脚本):

     class Program
        {
            static void Main(string[] args)
            {
                //连接数据库
                var client = new MongoClient("mongodb://root:root@192.168.100.3:27017/");
                //获取database
                var mydb = client.GetDatabase("myDb");
                //获取collection
                var collection = mydb.GetCollection<Userinfo>("userinfos");
                var filter = Builders<Userinfo>.Filter;
                var sort = Builders<Userinfo>.Sort;
                List<Userinfo> userinfos = collection.Find(filter.Lt("age", 25))    //查询年龄小于25岁的记录
                                                     .Sort(sort.Descending("age"))  //按年龄进行倒序
                                             .ToList();
                //遍历结果
                userinfos.ForEach(u => Console.WriteLine($"姓名:{u.name},年龄:{u.age},英文名:{u.ename.firstname} {u.ename.lastname}"));
                Console.ReadKey();
            }
    
            /// <summary>
            /// 用户类
            /// </summary>
            public class Userinfo
            {
                public int _id { get; set; }//id
                public string name { get; set; }//姓名
                public int age { get; set; }//年龄
                public int level { get; set; }//等级
                public Ename ename { get; set; }//英文名
                public string[] roles { get; set; }//角色
                public string address { get; set; }//地址
            }
    
            /// <summary>
            /// 英文名
            /// </summary>
            public class Ename
            {
                public string firstname { get; set; }
                public string lastname { get; set; }
            }


    执行结果如下:

     

    2 常用属性  

    上边的例子仅仅用了基本的自动化映射,使用基本的自动化映射时:类和Bson中的字段必须严格一致(_id除外,可以自动映射到_id/id/Id),且Bson中的每一个字段在实体类中都必须有一个对应的字段,不然就会抛出异常,这就造成我们可能要写一个非常庞大的实体类,而且类中的字段命名也要严格和Bson中的字段一致。这些限制对我们开发来说是不能接受的,这里我们采用mongoDriver中的一些属性改进一下上边的代码,如下:

     class Program
        {
            static void Main(string[] args)
            {
                //连接数据库
                var client = new MongoClient("mongodb://root:root@192.168.100.3:27017/");
                //获取database
                var mydb = client.GetDatabase("myDb");
                //获取collection
                var collection = mydb.GetCollection<Userinfo>("userinfos");
    
                var filter = Builders<Userinfo>.Filter;
                var sort = Builders<Userinfo>.Sort;
                List<Userinfo> userinfos = collection.Find(filter.Lt("age", 25))    //查询年龄小于25岁的记录
                                                     .Sort(sort.Descending("age"))  //按年龄进行倒序
                                             .ToList();
                //遍历结果
                userinfos.ForEach(u =>
                {
                    Console.WriteLine($"编号:{u.userId},姓名:{u.name},年龄:{u.age},英文名:{u.ename?.ming} {u.ename?.xing},性别:{u.gender}");
                    Console.WriteLine($"其他属性:{u.otherprops}");
                    Console.WriteLine();
                });
    
                Console.ReadKey();
            }
    
            /// <summary>
            /// 用户类
            /// </summary
            //[BsonIgnoreExtraElements]
            public class Userinfo
            {
                [BsonId]
                public int userId { get; set; }//id
                public string name { get; set; }//姓名
                public int age { get; set; }//年龄
                public Ename ename { get; set; }//英文名
                [BsonDefaultValue('')]
                public char gender { get; set; }
                [BsonIgnore]
                public string nickname { get; set; }//昵称
                [BsonExtraElements]
                public BsonDocument otherprops { get; set; }//其他属性
            }
            /// <summary>
            /// 英文名
            /// </summary>
            public class Ename
            {
                [BsonElement("firstname")]
                public string ming { get; set; }
                [BsonElement("lastname")]
                public string xing { get; set; }
            }

    执行结果如下:

     

    这里用到了几个常用的属性,作用如下:

      BsonId修饰的字段对应BsonDocument中的_id;

      BsonDefaultValue(value)用于指定默认值;

      BsonIgnore表示不映射,即使BsonDocument中包含该字段也不会赋值给属性;

      BsonExtraElements修饰的字段用于存储没有映射到类中的其他属性;

      BsonElement可以指定修饰的属性映射到BsonDocument中的哪个字段,

    还有一些其他的属性,具体可以参考官方文档。

    3 MongoDB使用Linq查询 

     MongoDB的驱动支持Linq查询,用法十分简单,引用  usingMongoDB.Driver.Linq;  后,使用  collection.AsQueryable()  获取IMongoQueryable<T>实例,然后就可以使用Linq对这个IMongoQueryable<T>进行查询了。

      使用过EF的小伙伴应该都了解IQueryable+Linq的查询默认不是将整个结果集立即加载到内存中,而是延迟加载的,即只有使用结果时(如 在执行First,Last,Single,Count,ToList等)才会将Linq转换成Sql,在数据库中执行查询操作。类似的,在使用IMongoQueryable<T>+Linq进行查询时默认也是延迟加载的,在需要使用查询结果时,驱动会将Linq转换成聚合管道命令(aggregation pipeline),如Linq中的Where被转换成$watch,Join转换为$lookup,Skip和Take转换为$skip和$limit等等,然后在Mongodb中执行这些管道命令获取结果,看一个栗子我们就会轻松地掌握了。

    首先添加一些测试数据:

    //添加学生数据
    db.students.insertMany([
        {"no":1, "stuName":"jack", "age":23, "classNo":1},
        {"no":2, "stuName":"tom", "age":20, "classNo":2},
        {"no":3, "stuName":"hanmeimei", "age":22, "classNo":1},
        {"no":4, "stuName":"lilei", "age":24, "classNo":2}
        ])
            
    //添加班级数据
    db.classes.insertMany([
        {"no" : 1,"clsName" : "A班"},
        {"no" : 2,"clsName" : "B班"}
        ])

    这里查找了两组数据:①基本查询:查找年龄大于22岁的学生;②连接查询:查询各个学生的学号、姓名、班级名。例子比较简单,直接看代码吧

    namespace ConsoleAppCore
    {
        using System;
        using MongoDB.Bson;
        using MongoDB.Bson.Serialization.Attributes;
        using MongoDB.Driver;
        using MongoDB.Driver.Linq;
        using System.Collections.Generic;
        class Program
        {
            static void Main(string[] args)
            {
                //连接数据库
                var client = new MongoClient("mongodb://root:root@192.168.100.3:27017/");
                //获取database
                var mydb = client.GetDatabase("myDb");
                //获取collection
                var stuCollection = mydb.GetCollection<Student>("students");
                var clsCollection = mydb.GetCollection<Classx>("classes");
                //查找年龄大于22的学生
                Console.WriteLine("-------------查找年龄大于22的学生列表--------------");
                //1.query语法
                List<Student> stuList1 = (from stu in stuCollection.AsQueryable()
                                          where stu.age > 22
                                          select stu).ToList();
                //2.点语法
                List<Student> stuList2 = stuCollection.AsQueryable().Where(s => s.age > 22).ToList();
                stuList1.ForEach(stu => Console.WriteLine($"姓名:{stu?.stuName},  年龄:{stu?.age}"));
                Console.WriteLine();
    
                //表连接查询,查询各个学生的班级名
                Console.WriteLine("-------------表连接,查询学生的班级名----------------");
                //1.query语法
                var result1 = from stu in stuCollection.AsQueryable()
                              join cls in clsCollection.AsQueryable()
                                on stu.classNo equals cls.no
                              select new { stuno = stu.no, stu.stuName, cls.clsName };
                //2.点语法
                var result2 = stuCollection.AsQueryable().Join(
                                clsCollection.AsQueryable(),
                                stu => stu.classNo,
                                cls => cls.no,
                                (stu, cls) => new { stuno = stu.no, stu.stuName, cls.clsName }
                             );
                //遍历结果
                foreach (var item in result1)
                {
                    Console.WriteLine($"学号:{item.stuno}, 姓名:{item.stuName}, 班级:{item.clsName}");
                }
    
                Console.ReadKey();
            }
            /// <summary>
            /// 学生类
            /// </summary
            public class Student
            {
                public int no { get; set; }//学号
                public string stuName { get; set; }//姓名
                public int age { get; set; }//年龄
                public int classNo { get; set; }//班级编号
                [BsonExtraElements]
                public BsonDocument others { get; set; }
            }
            /// <summary>
            /// 班级类
            /// </summary>
            public class Classx
            {
                public int no { get; set; }//班级编号
                public string clsName { get; set; }//班级名
                [BsonExtraElements]
                public BsonDocument others { get; set; }
            }
        }
    }

    执行结果如下:



  • 相关阅读:
    大小端判断
    引用计数
    STL_ALGORITHM_H
    书单一览
    GIT版本控制系统(二)
    JS随机数生成算法
    STL学习笔记--临时对象的产生与运用
    乱序优化与GCC的bug
    你的灯亮着吗?
    交换机和路由器
  • 原文地址:https://www.cnblogs.com/majiang/p/11225160.html
Copyright © 2020-2023  润新知