. NET Framework下使用MongoDB示例

1. 新建一个控制台项目

  选择.net framework版本为4.6,最新的mongodb驱动nuget需要达到4.5.2以上,所以选择了4.6版本。

2. 引入nuget包

  MongoDB.Driver和MongoDB.Bson

3. MongoDB连接配置 

// 连接地址
string connectionStr = "mongodb://localhost:27017";
// 数据库名
string databaseName = "test";
// 表名
string dbName = "tests";
// 创建连接
var mongoClient = new MongoClient(connectionStr);
var mongoDb = mongoClient.GetDatabase(databaseName);
var collection = mongoDb.GetCollection<User>(dbName);

  新建了一个user类

public class User
{
public string _id { get; set; }
public int Age { get; set; }
public string Name { get; set; }
public User Son { get; set; }
public DateTime BirthDateTime { get; set; }
}

  

4. 简单增删改查

4.1 查询

4.1.1 根据filter字段来查

  查询代码

// 过滤条件
var filter = Builders<User>.Filter.Eq(u => u.Name, "CeShi");
var filterALL = Builders<User>.Filter.Where(u => u._id != null);

// 查询结果
var resultList = collection.Find(filterALL).ToList();
Console.WriteLine("查询结果");

int i = 1;
foreach (var result in resultList)
{
    Console.WriteLine($"//{i}");
    Console.WriteLine("{");
    Console.WriteLine($""id":"{result.id}","Age":"{result.Age}","Name":"{result.Name}",");
    Console.WriteLine(""Son":{");
    if (result.Son != null && result.Son.Age > 0)
    {
        Console.WriteLine($""Age":"{result.Son.Age}","Name":"{result.Son.Name}"");
    }
    Console.WriteLine("},");
    Console.WriteLine($""BirthDateTime":"{result.BirthDateTime}"");
    Console.WriteLine("}");
    i++;
}

  第一种查询eq方式为根据条件来查的,注意这个时候会区分大小写的。第二种filter是尝试查询全部数据,但是没有找到相关方法,写的一个代替品,因为_id的值是肯定有的,所以这么写了。

  第一中查询方式结果

 

   第二种where查询结果

 4.1.2 使用linq的方式也可以进行查询

  进行全部查询,如

//var query = from u in collection.AsQueryable()
//                     select new { u.Name, u.age };

var query = from u in collection.AsQueryable()
                    select u;

var resultList = query.ToList();`

  这样查出的结果如下

 

   linq里可以使用where条件来过滤数据

 

   查询子文档中的数据

 

4.2 新增

4.2.1 添加一条数据

// 自定义主键
var id = Guid.NewGuid().ToString();

// 要添加的数据实体
var user = new User
{
    _id = id,
    Age = 26,
    Name = "CeShi",
    Son = new User
    {
        Age = 1,
        Name = "ceshi"
    },
    BirthDateTime = DateTime.Now
};

//添加一条数据
collection.InsertOne(user);`

  

4.2.2 添加多条数据

 List<User> userListAdd = new List<User>();
User userAdd1 = new User
{
    _id = Guid.NewGuid().ToString(),
    Age = 23,
    Name = "zhangsan",
    BirthDateTime = DateTime.Now.AddYears(-22)
};
userListAdd.Add(userAdd1);

User userAdd2 = new User
{
    _id = Guid.NewGuid().ToString(),
    Age = 33,
    Name = "Adamas",
    Son = new User
    {
        Age = 3,
        Name = "Adams",
        BirthDateTime = DateTime.Now.AddYears(-2)
    },
    BirthDateTime = DateTime.Now.AddYears(-32)
};
userListAdd.Add(userAdd2);

// 添加多条使用 InsertMany()方法
collection.InsertMany(userListAdd);

  

4.3 修改更新

4.3.1 简单更新

  使用主键或其他字段进行更新,如将Name为zhagnsan的son赋值

var filter = Builders<User>.Filter.Eq("Name", "zhangsan");

var son = new User {
                        Age = 2,
                        Name = "zhangxiao",
                        BirthDateTime = DateTime.Now.AddYears(-1)
                    };

// 更新数据
var update = Builders<User>.Update.Set("Son", son);

// 执行更新操作 更新一条数据
UpdateResult upResult = collection.UpdateOne(filter, update);

// 得到更新数据条数
var upCount = upResult.ModifiedCount;`    

  结果如下

 

   如果想更新多条数据,则配合查询条件,使用collection.UpdateMany

// 过滤条件
var filter = Builders<User>.Filter.Where(u=>u.Name== "CeShi");

// 更新数据
var update = Builders<User>.Update.Set("age", "25");

// 执行更新操作 更新多条
UpdateResult upResult = collection.UpdateMany(filter, update);

// 得到更新数据条数
var upCount=upResult.ModifiedCount;

  

4.3.2 根据子集合属性更新

  根据son的Name的值为“zhangxiao”,将他的年龄修改为4

// 过滤条件
var filter = Builders<User>.Filter.Where(u=>u.Son.Name== "zhangxiao");

var son = new User
{
    Age = 4,
    Name = "zhangxiao",
    BirthDateTime = DateTime.Now.AddYears(-3)
};

// 更新数据
var update = Builders<User>.Update.Set("Son", son);

// 执行更新操作 更新一条数据;更新多条,使用UpdateMany
UpdateResult upResult = collection.UpdateOne(filter, update);

// 得到更新数据条数
var upCount = upResult.ModifiedCount;`

  结果如下

 

 4.4 删除

4.4.1 根据主键或其他条件删除

  将name为“CeShi”的数据删除

var filter = Builders<User>.Filter.Where(u => u.Name == "CeShi");
 // 删除一条数据
 DeleteResult deResult = collection.DeleteMany(filter); 
// 得到删除条数 
var deCount = deResult.DeletedCount; 
Console.WriteLine($"删除条数{deCount.ToString()}");

  结果查询,已经将name为“CeShi”的数据删除了

 

 4.4.2 根据子集合属性删除

  删除子文档son里name为“zhangxiao”的数据

var filter = Builders<User>.Filter.Where(u => u.Son.Name == "zhangxiao");
 // 删除一条数据 
DeleteResult deResult = collection.DeleteMany(filter); 
// 得到删除条数 
var deCount = deResult.DeletedCount; 
Console.WriteLine($"删除条数{deCount.ToString()}");

  结果查询,已经没有子文档son里name为“zhangxiao”的数据了

 

5. MongoDB命令对应的操作

5.1 $project

  $project类似于sql中的select,筛选出我们要的显示字段,如我们想选出所有数据的Name和Age字段

var query = from p in collection.AsQueryable() 
                select new { p.Name, p.Age };
 // 或者 
//var query = collection.AsQueryable() 
//         .Select(p => new { p.Name, p.Age });

  结果如下

 

5.2 $sort

  排序。我们根据年龄降序和姓名升序的方式查找数据

var query = from p in collection.AsQueryable()
                orderby p.Name, p.Age 
                descending select p; 
// 或者 
//var query = collection.AsQueryable() .OrderBy(p => p.Name).ThenByDescending(p => p.Age);

  结果如下

 

5.3 $limit

类似于linq中的take,选取多少条数据

var query = collection.AsQueryable().Take(2);

  结果如下

 

5.4 $skip

  类似于linq下的skip,跳过m条数据,配合take使用,即跳过m条数据取n条数据

var query = collection.AsQueryable().Skip(1).Take(1);

  结果如下

 

5.5 $group

  分组

var query = from p in collection.AsQueryable() 
                group p by p.Age into g 
                select new { Age = g.Key, Count = g.Count() }; 
// 或者
 //var query = collection.AsQueryable()
 // .GroupBy(p => p.Age )
 // .Select(g => new { Age = g.Key, Count = g.Count() });    

  结果如下

 

5.6 $lookup 表联合查询

  类似于ef中的左连接

var query = from u in collect.AsQueryable()
                    join o in coll.AsQueryable() on u.Name equals o.Name
                     select new { u._id, u.son, o.Id,o.Name };
 var result = query.ToList();    

  由于测试库没有建立第二张表,就简单放一下测试语句

5.7 Distinct

  去重。我们查询年龄去重的值

var query = collection.AsQueryable() 
                .Select(p => new { p.Age }) 
                .Distinct();

  结果如下

 

5.8 其他

  请自行参照官方文档,官方文档网址:https://docs.mongodb.com/v3.4/reference/operator/query/

6 c#操作Mongo查询

6.1 插入表结构

  新建类

class BsonDocument 
{ 
    public ObjectId _id { get; set; }
    public string Item { get; set; }
    public int Num { get; set; } 
    public List<ArrayDocument> Instock { get; set; } 
}

public class ArrayDocument
{
    public string WareHouse { get; set; }
    public string Qty { get; set; }
}

  插入数据库

var documents = new[] { new BsonDocument{ Item="journal", Num=15, Instock=new List<ArrayDocument>(){ new ArrayDocument { WareHouse = "A", Qty = "5" }, new ArrayDocument { WareHouse = "C", Qty = "15" } } }, new BsonDocument{ Item="notebook", Num=5, Instock=new List<ArrayDocument>(){ new ArrayDocument { WareHouse = "C", Qty = "5" } } }, new BsonDocument{ Item="paper", Num=30, Instock=new List<ArrayDocument>(){ new ArrayDocument { WareHouse = "A", Qty = "60" }, new ArrayDocument { WareHouse = "B", Qty = "15" } } } , new BsonDocument{ Item="planner", Num=22, Instock=new List<ArrayDocument>(){ new ArrayDocument { WareHouse = "A", Qty = "40" }, new ArrayDocument { WareHouse = "B", Qty = "5" } } }, new BsonDocument{ Item="postcard", Num=2, Instock=new List<ArrayDocument>(){ new ArrayDocument { WareHouse = "B", Qty = "15" }, new ArrayDocument { WareHouse = "C", Qty = "35" } } } };

collection.InsertMany(documents);

  

6.2 普通查询

6.2.1 查询指定item的值

  代码

var filter = Builders<BsonDocument>.Filter.Eq("Item", "paper"); 
var result = collection.Find(filter).ToList();

  结果

 

6.2.2 查询Num值大于1的

  代码

var filter = Builders<BsonDocument>.Filter.Gt("Num", 1); 
var result = collection.Find(filter).ToList();

  结果

 

6.2.3 and多条件查询

  代码

//创建过滤器生成器对象 
FilterDefinitionBuilder<BsonDocument> filterBuilder = Builders<BsonDocument>.Filter;
 //创建过滤器 
var filter = Builders<BsonDocument>.Filter.And(filterBuilder.Gt("Num", 1), filterBuilder.Eq("Item", "notebook")); 
var result = collection.Find(filter).ToList();

  结果

 

6.2.4 or多条件查询

  代码

//创建过滤器生成器对象 
FilterDefinitionBuilder<BsonDocument> filterBuilder = Builders<BsonDocument>.Filter; 
//创建过滤器 
var filter = Builders<BsonDocument>.Filter.Or(filterBuilder.Gt("Num", 5), filterBuilder.Eq("Item", "notebook")); 
var result = collection.Find(filter).ToList();

  结果

 

6.2.5 not查询

  查找num小于10

  代码

//创建过滤器生成器对象
FilterDefinitionBuilder<BsonDocument> filterBuilder = Builders<BsonDocument>.Filter;
//创建过滤器
var filter = Builders<BsonDocument>.Filter.Not(filterBuilder.Gt("Num", 10));
var result = collection.Find(filter).ToList();

  结果

 

6.2.6 排序

  代码

//排序规则   Ascending 正序  Descending 倒序
SortDefinition<BsonDocument> sort = Builders<BsonDocument>.Sort.Descending("Num");
var result = collection.Find(Builders<BsonDocument>.Filter.Empty).Sort(sort).ToList();

  结果

 

  

6.2.6 in查询

  代码

var filter = Builders<BsonDocument>.Filter.In("Item", new[] { "journal", "notebook" });
var result = collection.Find(filter).ToList();

  结果

 

6.2.6 Not In 查询

  代码

var filter = Builders<BsonDocument>.Filter.Nin("Item", new[] { "journal", "notebook" });
var result = collection.Find(filter).ToList();

  结果

 

6.2.7 分页查询

  代码

//Skip跳过多少页  Limit 获取多少页
var result = collection.Find(Builders<BsonDocument>.Filter.Empty).Skip(1).Limit(1).ToList();

  结果

 

6.2.8 查询总记录数

  代码

var result = collection.Find(Builders<BsonDocument>.Filter.Empty).Count();

  结果

 

6.2.9 查询指定属性

  代码

ProjectionDefinition<BsonDocument> projection = Builders<BsonDocument>.Projection.Include("Item").Exclude("_id");
var result = collection.Find(Builders<BsonDocument>.Filter.Empty).Project(projection).ToList();

  结果

 

6.3 嵌套查询

6.3.1 条件为嵌套文档字段时加“.

  代码

var filter = Builders<BsonDocument>.Filter.Eq("Instock.WareHouse", "B");
var result = collection.Find(filter).ToList();

  结果

 

6.3.2 嵌套文档数组元素与指定条件匹配的所有文档   

  顺序必须一致

  代码

var filter = Builders<BsonDocument>.Filter.AnyEq("Instock", new ArrayDocument { WareHouse="A" ,Qty="5" });
var result = collection.Find(filter).ToList();

  结果

 

6.3.3 嵌套文档数组中符合其中一个条件的查询

  代码

var filter = Builders<BsonDocument>.Filter.Gt("Instock.0.Qty", 15);
var result = collection.Find(filter).ToList();

  结果

 

  

6.3.4 指定嵌套文档数组索引的元素条件

  代码

var filter = Builders<BsonDocument>.Filter.Gt("Instock.0.Qty", 15);
var result = collection.Find(filter).ToList();

  结果同上

6.3.5 $ElemMatch查询

嵌套文档数组中至少有一个满足条件

代码 

//创建过滤器生成器对象
FilterDefinitionBuilder<BsonDocument> filterBuilder = Builders<BsonDocument>.Filter;

//创建过滤器
FilterDefinition<BsonDocument> filter = filterBuilder.ElemMatch<BsonDocument>("instock", new ArrayDocument{ Qty = "5", WareHouse = "A" });

  

6.3.6 不使用ElemMatch的多条件查询,  只要文档数组中满足即可

代码

//创建过滤器生成器对象
FilterDefinitionBuilder<BsonDocument> filterBuilder = Builders<BsonDocument>.Filter;

//创建过滤器
FilterDefinition<BsonDocument> filter = filterBuilder.And(filterBuilder.Eq("Instock.Qty",5),filterBuilder.Eq("Instock.WareHouse", "A"));

var result = collection.Find(filter).ToList();

   

6.3.7 查询嵌套文档中符合要求的嵌套文档数据  

  使用BsonDocument (奇葩使用)

ProjectionDefinition<BsonDocument> projection = Builders<BsonDocument>.Projection.Include("instock").Exclude("_id");

//unwind  展开数组    AppendStage 添加聚合条件    
var result = coll.Aggregate().Unwind("instock").AppendStage<BsonDocument>(new BsonDocument { { "$match", new BsonDocument("instock.qty", new BsonDocument("$gt", 30)) } }
).Project(projection).ToList();

  使用强模型  mongo会将decimal类型变成字符串存储 ,所以不可使用decimal类型

  准备数据

IList<User> users = new List<User>
{
    new User
    {
        ID = "1",
        Name = "狗娃",
        Age = 11,
        Order = new List<Order>
        {
            new Order{Name="订单1",Price=111},
            new Order{Name="订单2",Price=222},
            new Order{Name="订单3",Price=333},
        }
    },
    new User
    {
        ID = "2",
        Name = "铁蛋",
        Age = 11,
        Order = new List<Order>
        {
            new Order{Name="订单4",Price=666},
            new Order{Name="订单5",Price=454},
            new Order{Name="订单6",Price=87},
        }
    },
    new User
    {
        ID = "3",
        Name = "狗剩",
        Age = 11,
        Order = new List<Order>
        {
            new Order{Name="订单7",Price=1},
            new Order{Name="订单8",Price=345},
            new Order{Name="订单9",Price=653},
        }
    }
};

//selectMany 展开子文档数组
var res = coll.AsQueryable().SelectMany(y => y.Order).Where(y=>y.Price>555).ToList();

6.4 查询NULL值属性

6.4.1 数据表

var documents = new[]
{
    new BsonDocument { { "_id", 1 }, { "item", BsonNull.Value } },
    new BsonDocument { { "_id", 2 } }
};

var documents = new[] {
                new BsonDocument {
                    Item = null
                },
                new BsonDocument {
                }
            };
collection.InsertMany(documents);

6.4.2 查询值为null或者不存在的数据

  代码

var filter = Builders<BsonDocument>.Filter.Eq("Item", BsonNull.Value);
var result = collection.Find(filter).ToList();

   

6.4.3 查询值为null的数据

  代码

var filter = Builders<BsonDocument>.Filter.Where(u=>u.Item==null);           
var result = collection.Find(filter).ToList();

  结果

 

6.4.4 存在检查/查询不存在/存在此属性的值

  代码

var filter = Builders<BsonDocument>.Filter.Exists("Item",false);            
var result = collection.Find(filter).ToList();

  

 

 

原文地址:https://www.cnblogs.com/Lvkang/p/13974880.html