Skip to content

mongodb 实例

约 668 字大约 2 分钟

组件

2025-08-29

简介

文档数据库。灵活高效,数据结构灵活的mysql。 本质上就是用于读写集合文档的服务进程

文档: mysql的; 集合:mysql的

集合

由多个文档组成

文档

文档本来是存储JSON的,但是mongo支持直接存储二进制,所以进化为了Binary JSON => BSON

数据页

将集合持久化存储到磁盘 形成后缀为.wt的文件,每页32kb,读取大集合时 只需要读取指定的页,减少开销

特性

  • 索引使用变种B+树
  • 不加锁,写时复制: 因为不加锁 所以在写入时会复制原有节点进行写入,而不影响读取。后面将写入的节点合并回去

mongodb安装

下一步下一步 complete 选第一项

使用 查询28W条 4.5s 查询不要加投影,会更慢,因为服务器需要每条处理投影

private readonly IMongoCollection<CellDetection> _collectiond;
private readonly IMongoCollection<BsonDocument> _bsonDocument;
public MainWindow()
{
    InitializeComponent();
    var database = App.ServiceProvider.GetRequiredService<IMongoDatabase>();
    _collectiond = database.GetCollection<CellDetection>("celld");
    _bsonDocument = database.GetCollection<BsonDocument>("celld");
    var serverStatus = database.RunCommand<BsonDocument>(new BsonDocument("serverStatus", 1));
    this.Title = "连接成功!服务器版本:" + serverStatus["version"];
}

add()
{
	List<CellDetection> cellds = new List<CellDetection>();
	//var json = File.ReadAllText("./250819140610052_PBClabelInfo.txt");
	
	using (var streamReader = new StreamReader("./250819140610052_PBClabelInfo.txt"))
	using (var jsonReader = new JsonTextReader(streamReader))
	{
	    jsonReader.SupportMultipleContent = true; // 支持多行 JSON
	    var serializer = new JsonSerializer();
	    var insertOpt = new InsertManyOptions { IsOrdered = false };
	    // JSON 文件是一个数组,逐个读取对象
	    while (await jsonReader.ReadAsync())
	    {
	        if (jsonReader.TokenType == JsonToken.StartObject)
	        {
	            var d = serializer.Deserialize<CellDetection>(jsonReader);
	            cellds.Add(d);
	            if (cellds.Count >= 1000)
	            {
	                await _collectiond.InsertManyAsync(cellds, insertOpt);
	                cellds.Clear();
	            }
	        }
	    }
	    if (cellds.Count > 0)  //17912ms  28W
	    {
	        await _collectiond.InsertManyAsync(cellds, insertOpt);
	    }
	}
}

load()
{
    Stopwatch sw = Stopwatch.StartNew();
    var aa = await _collectiond.Find(_ => true).ToListAsync();

	//加了投影更慢
	//var projection = Builders<CellDetection>.Projection.Exclude("_id"); //排除id
    //var aa = await _collectiond.Find(_ => true).Project(projection).ToListAsync();

    sw.Stop();
    Debug.WriteLine(sw.ElapsedMilliseconds + "ms"); //28w 5567ms


	sw.Restart();
	var projection1 = Builders<BsonDocument>.Projection
    .Exclude("_id")
    .Include("CellNumber")
       .Include("DetectionCode")
       .Include("DetectionName")
       .Include("DetectionGroupCode")
       .Include("StartPonit")
       .Include("EndPonit")
       .Include("ExamineState")
       .Include("SourceDetectionName")
       .Include("Width")
       .Include("Height")
       .Include("ImgName")
       .Include("Image")
       .Include("SildeIndexX")
       .Include("SildeIndexY")
       .Include("Confidence");
	var dds = await _bsonDocument.Find(_ => true).Project(projection1).ToListAsync();
	sw.Stop();
	Debug.WriteLine(sw.ElapsedMilliseconds + "msss"); //7453ms

}

使用流式加载

 private async void Button_Click_1(object sender, RoutedEventArgs e)
{
    Stopwatch sw = Stopwatch.StartNew();

    //sw.Restart();
    //var aa = await _collectiond.Find(_ => true).ToListAsync();
    //sw.Stop();
    //Debug.WriteLine(sw.ElapsedMilliseconds + "ms"); //28w 5567ms

    //var totalCount = await _collectiond.CountDocumentsAsync(_ => true);
    var totalCount1 = await _collectiond.CountDocumentsAsync(t => t.DetectionCode.Equals("红细胞"));
    var totalCount2 = await _collectiond.CountDocumentsAsync(t => t.DetectionCode.Equals("血小板"));
    var totalCount3 = await _collectiond.CountDocumentsAsync(t => t.DetectionCode.Equals("呈缗钱状排列红细胞"));
    sw.Stop();
    Debug.WriteLine($"记录数: {totalCount1}{totalCount2}{totalCount3}{sw.ElapsedMilliseconds}ms");




    sw.Restart();
    //流式查询
    var detections = new List<CellDetection>();
    // 定义 FindOptions 并设置 BatchSize
    var options = new FindOptions<CellDetection, CellDetection>
    {
        BatchSize = 10000 // 每批次加载 1000 条记录
    };
    // 步骤2: 定义投影(排除 _id 和 Image)
    var projection = Builders<CellDetection>.Projection
        .Exclude(x => x.Id);
    using (var cursor = await _collectiond.FindAsync(_ => true, options)
        //.Project<CellDetection>(projection)
        //.ToCursorAsync()
        )
    {
        while (await cursor.MoveNextAsync())
        {
            var batch = cursor.Current.ToList();
            detections.AddRange(batch);
            //await Dispatcher.InvokeAsync(() =>
            //{
            //    //PeopleListView.ItemsSource = detections;
            //    Debug.WriteLine($"已加载 {detections.Count} / {totalCount} 条");
            //});
        }
    }
    sw.Stop();
    Debug.WriteLine(sw.ElapsedMilliseconds + "ms"); //28w 7067ms
}
/*
* 记录数: 258711,671,22793。374ms
* 5620ms
*/