MongoDB 版本 2 某些操作
MongoDB 版本 2 驱动程序的 CRUD 及其过滤功能
引言
互联网上有很多关于如何使用 MongoDB 驱动程序版本 1 的手册,但关于版本 2 的不多。我想补充一些关于使用版本 2 的信息。
那么,让我们从读取开始
在 MongoDB 中,读取可以被认为是以下选项
- 查找所有文档
- 过滤
- 排序
- 定义和构建器
在 MongoDB 中创建文档很简单。您可以使用 Insert(字母 C)来完成。
在这里,您有很多选项
- 替换
- 更新
- Upsert(更新插入)
我还要提到删除,或者字母 D。
另外,我想描述如何使用 projections(投影)来限制您从 MongoDB 中获取的内容。
那么,让我们从在 MongoDB 中同步查找一些信息开始。
假设我有以下类声明
public abstract class MongoEntityBase
    {
        // ReSharper disable once InconsistentNaming
        public ObjectId _id { get; set; }
    }
 
    public class SampleClarification : MongoEntityBase
    {
        public ObjectId SomeId { get; set; }
        public int RectificationNumber { get; set; }
        public string RectificationReason { get; set; }
        public string RectificationText { get; set; }
    }
这个类将使我可以操作 MongoDB 数据库中的 SampleClarification 集合。
另外,请看 MongoDB 的数据库上下文的默认构建
public class SampleDataContext
    {
        public IMongoDatabase Database;
 
        public SampleDataContext()
        {
            var client = new MongoClient("https://:27017/sample");
            Database = client.GetDatabase("sample");
        }
    }
为了**同步**获取这个集合,我需要向 datacontext 添加接口集合。数据上下文将被转换为这样
public class SampleDataContext
    {
        public IMongoDatabase Database;
        public SampleDataContext()
        {
            var client = new MongoClient("https://:27017/sample");
            Database = client.GetDatabase("sample");
        }
        public IMongoCollection<SampleClarification> 
        SampleClarifications => Database.GetCollection<SampleClarification>("sample");
    }
这里最重要的部分是 SampleClarifications。
然后,您可以用以下方式搜索所有 SampleClarifications
SampleDataContext sc = new SampleDataContext();
var allDocs = sc.SampleClarifications.Find(new BsonDocument()).ToList();
然后,allDocs 将在内存中列出所有文档。
所以,那是一个同步调用。
现在我想演示一个异步调用(这将像蛋糕一样简单)
SampleDataContext sc = new SampleDataContext();
var allDocs = await sc.SampleClarifications.Find(new BsonDocument()).ToListAsync();
但是,假设您想遍历返回的文档,并对它们做一些事情。那么函数 ForEachAsync 非常方便。我建议将其与 cursor(游标) 一起使用。
接下来是过滤。过滤的一种方法如下
SampleDataContext sc = new SampleDataContext();
            var allDocs = await sc.SampleClarifications.Find(new BsonDocument()
                    {
                        { "RectificationNumber" , 4}
                }
                ).ToListAsync();
您是否觉得使用字符串进行过滤不是一个好方法?如果是,您并不孤单。 MongoDB 驱动程序有一些用于过滤的新功能
SampleDataContext sc = new SampleDataContext();
           
var allDocs = await sc.SampleClarifications.
              Find(Builders<SampleClarification>.Filter.Gte
              (a => a.RectificationNumber, 7)).ToListAsync();
读取过滤器创建的一种方法可以是:构建一个 SampleClarification 类型的过滤器,该过滤器返回 SampleClarification 实例,其中 RectificationNumber 大于或等于 7。
其他可能性可以是 Lte - 小于等于,Eq - 等于,等等。
另一个有用的功能是使用 Where。例如,像这样
SampleDataContext sc = new SampleDataContext();
            
var allDocs = await sc.SampleClarifications.
              Find(Builders<SampleClarification>.Filter.Where
              (a => a.RectificationNumber == 7)).ToListAsync();
IMHO where 适用于您不想记住 Lte、Eq、Gte、Ne 等的情况。**但是 Where 有一个重要的特性。您可以在那里传递可空值。**
MongoDB 的另一个有趣的特性是组合过滤特性。见以下代码
SampleDataContext sc = new SampleDataContext();
 
var filter = Builders<SampleClarification>.Filter.Empty;
 
if (true /*some condition*/)
{
     filter = filter & Builders<SampleClarification>.Filter.Where
              (a => a.RectificationText.Contains("aaa"));
}
 
var allDocs = await sc.SampleClarifications.Find(filter).ToListAsync();
很有趣,是吧?当我看到 & 而不是 && 时,我很惊讶。
但这还不是全部。让我向您介绍另一个快捷方式:&=。像这样
if (true /* another condition */)
{
      filter &= Builders<SampleClarification>.Filter.Gte(a => a.RectificationNumber, 20);
}
排序
对于排序,您可以再次使用 Builder。可以像这样实现
SampleDataContext sc = new SampleDataContext();
 
var filter = Builders<SampleClarification>.Filter.Empty;
var sorting = Builders<SampleClarification>.Sort.Ascending(t => t.RectificationNumber);
var allDocs = await sc.SampleClarifications.Find(filter).Sort(sorting).ToListAsync();
如果您觉得为了 Sort 某些东西而输入大量内容很无聊,您可以查看 SortBy 函数
SampleDataContext sc = new SampleDataContext();
var filter = Builders<SampleClarification>.Filter.Empty;
var allDocs = await sc.SampleClarifications.Find(filter).SortBy
              (s => s.RectificationNumber).ToListAsync();
或者您可以使用更复杂的模式
SampleDataContext sc = new SampleDataContext();
var filter = Builders<SampleClarification>.Filter.Empty;
var allDocs = await sc.SampleClarifications.Find(filter).
              SortBy(s => s.RectificationNumber)
              .ThenByDescending(a => a.TenderId)
              .ThenBy(a => a.RectificationReason).ToListAsync();
插入,或 CRUD 中的 C
您可以插入一个元素或多个元素。这是一个如何创建一个的例子
SampleDataContext sc = new SampleDataContext();
var filter = Builders<SampleClarification>.Filter.Empty;
var clar = new SampleClarification();
clar.RectificationNumber = 10;
clar.RectificationReason = "some reason";
clar.RectificationText = "fasdfdas fdsfas";
await sc.SampleClarifications.InsertOneAsync(clar);
替换,或 CRUD 中几乎是 U 的操作
首先,什么是替换。 Replace 是指您找到文档,删除它,然后放入一个具有修改值的新文档。
首先,您需要找到元素,然后 update 其值,然后保存它。这是一个例子
SampleDataContext sc = new SampleDataContext();
//var filter = Builders<SampleClarification>.Filter.Where
//(r => r.TenderId == ObjectId.Parse("56d55f1d4ee6bc45a0d7b539"));
//var clar = sc.SampleClarifications.Find(filter).FirstOrDefault();
 
//or another way:
var clar =  sc.SampleClarifications.Find(a => a.TenderId == ObjectId.Parse
            ("56d55f1d4ee6bc45a0d7b539")).FirstOrDefault();
 
if (clar != null)
{
    sc.SampleClarifications.ReplaceOne(r => r._id == clar._id, clar);
}
Replace one 将搜索条件作为参数,并将替换传递的元素。
CRUD 中的 U 或更新
好吧,要进行 update,您需要带有更新策略的 Builder。参见代码示例
SampleDataContext sc = new SampleDataContext();
 
var text = "fasfds afasfas";
var clar =  sc.SampleClarifications.Find
            (a => a.TenderId == ObjectId.Parse("56d55f1d4ee6bc45a0d7b539")).FirstOrDefault();
var modificationsUpdate = Builders<SampleClarification>.Update
    .Set(a => a.RectificationReason, text)
    .Set(v => v.RectificationNumber, 35);
 
if (clar != null)
{
    sc.SampleClarifications.UpdateOne(c => c._id == clar._id, modificationsUpdate);
}
另外,如果您愿意,您可以使其异步。
CRUD 中的另一个 U 或 Upsert(更新插入)
Upsert 意味着以下内容。如果 upsert 选项设置为 true,则如果不存在匹配的文档,则将插入该文档。如果文档存在,则将被替换。
可能有用的代码
SampleDataContext sc = new SampleDataContext();
 
var text = "fasfds afasfas";
var clar =  sc.SampleClarifications.Find
            (a => a.TenderId == ObjectId.Parse("56d55f1d4ee6bc45a0d7b539")).FirstOrDefault();
UpdateOptions options = new UpdateOptions
{
    IsUpsert = true
};
 
if (clar != null)
{
    sc.SampleClarifications.ReplaceOne(c => c._id == clar._id, clar, options);
}
最后删除或 D
最后,您可以 delete 任何文档。这相对容易
SampleDataContext sc = new SampleDataContext();
sc.SampleClarifications.DeleteOne(a => a.RectificationNumber == 10);
投影
假设您不想返回完整的 SampleClarification 字段列表,而是返回它们的子集。为此,您可以使用投影。
想象一下,您不想从 SampleClarification 中提取所有字段,为此,您创建了以下视图类
public class SampleClarificationView : MongoEntityBase
    {
        public ObjectId TenderId { get; set; }
        public int RectificationNumber { get; set; }
    }
然后您可以使用投影
SampleDataContext sc = new SampleDataContext();
var filter = Builders<SampleClarification>.Filter.Empty;
var middle = sc.SampleClarifications.Find(filter).Project(r => new SampleClarificationView()
{
    _id =  r._id,
    TenderId = r.TenderId,
    RectificationNumber = r.RectificationNumber
});
var result = await middle.ToListAsync();
结果将不包含所有字段。
关注点
在本文中,我写下了我对 MongoDB 的 CRUD 操作以及过滤的观察。在编写本文时,我最惊讶的是 MongoDB 的 Projects,它只获取某些字段,而不是所有字段。
历史
- 2021 年 3 月 3 日:初始发布


