外观
mongodb 实例
简介
文档数据库。灵活高效,数据结构灵活的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
*/