如何使用.NET Core对MongoDB数据库进行编码以实现长尾词查询功能?

2026-03-26 23:061阅读0评论SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计2955个文字,预计阅读时间需要12分钟。

如何使用.NET Core对MongoDB数据库进行编码以实现长尾词查询功能?

MongoDB 是一种 NoSQL 数据库,主要特征是存储结构化数据。它基于分布式文件存储,是一种开源数据库系统。与传统的 SQL 数据库(如 MySQL、SQL Server)不同,MongoDB 以文档形式存储数据,更适合处理大量非结构化或半结构化数据。

浅入 MongoDB

MonogoDB 是什么

MongoDB 是 NoSQL 型数据库,主要特征是存储结构化数据,MongoDB 是基于分布式文件存储的开源数据库系统。

结构化数据

以往我们使用 Mysql、SqlServer 等数据库,数据都是一条条的。MongoDB 的结构化数据正是区别于这种列-行式的数据。

结构化数据具有层级关系:

例如:

{ name: "MongoDB", type: "database", count: 1, info: { x: 203, y: 102 } }

MongoDB 与关系型数据库

由于 MongoDB 中,没有表、行、列,因此初学 MongoDB 时可能会有困扰,这里给出一些 MongoDB 与 普通SQL数据库对应的术语。

SQL术语/概念MongoDB术语/概念解释/说明databasedatabase数据库tablecollection数据库表/集合rowdocument数据记录行/文档columnfield数据字段/域indexindex索引table joins非关系型数据库,表与表之间没关系primary keyprimary key主键,MongoDB自动将_id字段设置为主键

资料来源:www.runoob.com/mongodb/mongodb-databases-documents-collections.html

MongoDB 入门命令

使用 mongo 进入 MongoDB shell 后,可使用命令(相当于SQL)执行操作。

注: MongoDB 中,有一个自动的 _id 字段,此字段 MongoDB 自动设置为主键并自动生成值。

显示所有数据库(包含系统数据库):

show dbs

当前正在操作的数据库或集合:

如何使用.NET Core对MongoDB数据库进行编码以实现长尾词查询功能?

db

连接到指定数据库:

use {数据库名称}

显示所有集合:

show collections # 或 show tables

查看集合中的所有文档:

# MyCollection 是集合名称 db.getCollection("MyCollection").find() db.getCollection("MyCollection").find().limit(1000).skip(0)

可能你不信,笔者百度了很久,第一页没找到一篇合适的友好的 "mongoDB 查看集合中的所有文档",特别是 CSDN 的垃圾文真的多。建议别瞎折腾了,去下一个 Navicat Premium,操作的时候,底部会提示所用的命令。

另外 MongoDB 有很多实用工具:docs.mongodb.com/tools/

文档

MongoDB 中的文档(Document)即关系型数据库中的一条记录(row)、一行数据。

但, MongoDB 中,一个集合(Collection-Table)中,是不需要具有相同字段的。例如:

A 文档:

{ name: "MongoDB", type: "database", count: 1, info: { x: 203, y: 102 } }

B 文档:

{ name: "MongoDB", typeName: "database", dataCount: 1, dataInfo: { m: 203, n: 102 } }

.NET Core 示例

我们从一个基础模板开始。

创建一个控制台程序,打开 Nuget 搜索并安装MongoDB.Driver

var client = new MongoClient("mongodb://{MongoDB}:27017"); IMongoDatabase database = client.GetDatabase("Test");

集合

可以通过CreateCollection()CreateCollectionAsync()创建一个集合,跟普通数据库不同的是,创建集合时是不需要指定结构的,只需要指定名称即可:

await database.CreateCollectionAsync("Test");

获取集合

GetCollection()函数可以让我们获取到集合,如果集合不存在,则会自动创建。

IMongoCollection<TDocument> GetCollection<TDocument>()

由于同一个集合可以有不同字段和字段类型的文档,因此几个文档如果有所差别,是很难统一起来的,例如:

(N/A) 代表此文档没有这个字段;如果一个文档有 10 个字段,另一个文档有 8 个字段,但是两者的字段完全不同时,要合并起来来,就有 18 个字段了。很明显,不应该汇集在一起,而是应该使用强类型对其 ”归档“ 。

创建两个类,分别为 Test1,Test2,其内容如下:

public class Test1 { public string Name { get; set; } } public class Test2 { public string DataType { get; set; } }

以两种文档类型获取集合:

var collection1 = database.GetCollection<Test1>("Test"); var collection2 = database.GetCollection<Test2>("Test");

这个获取集合的意思是,获取此集合中这类格式的文档的操作能力。

往集合中插入数据:

collection1.InsertOne(new Test1 { Name = "Test1" }); collection2.InsertOne(new Test2 { DataType = "Test2" }); // await collection.InsertOneAsync(object);

启动,查看结果。

InsertMany()可以插入批量数据:

Test1[] datas = new Test1[] { new Test1 { Name = "Test1" } }; collection1.InsertMany(datas);

统计数量

获取集合中所有的文档数:

collection1.CountDocuments(new BsonDocument()) // await collection1.CountDocumentsAsync(new BsonDocument());

任意一个文档集合对象,使用CountDocuments(new BsonDocument())都是获得此集合的所有文档数,而不是此类型的文档数。例如:

var collection1 = database.GetCollection<Test1>("Test"); collection1.CountDocuments(new BsonDocument())

获取的并不是 Test1 类型的文档数量,而是整个集合所有文档的数量。

原因是,CountDocuments()是一个过滤器函数,可以使用指定条件来筛选符合条件的文档的数量。指定条件后面会介绍。

查询

MongoDB 的查询并不像 LInq 中的表达式,基础了IEnumerableIEnumerable<T>接口,因此驱动没有WhereSelect这种表达式的查询方法。

Find()函数是查询函数,里面可以添加丰富的表达式,来筛选文档,当数据加载到本地内存后,即可使用丰富的表达式。

BsonDocument是一个类型,代表了要查询的文档筛选条件,如果BsonDocument对象没有添加任何属性,则代码没有筛选参数,则默认所有文档都符号条件。

我们把 Test1 和 Test2 类型,都加上一个属性:

public ObjectId _id { get; set; }

不然会报格式化错误:System.FormatException

如何序列化文档

document是文档对象, JsonSerializer 是 System.Text.Json 的静态类。

Console.WriteLine(JsonSerializer.Serialize(document));

查询第一条记录

var document = collection1.Find(new BsonDocument()).FirstOrDefault();

不加条件可能导致的问题

以下代码会导致程序报错:

var documents = await collection1.Find(new BsonDocument()).ToListAsync(); foreach(var item in documents) { Console.WriteLine(JsonSerializer.Serialize(item)); }

因为collection1是标记为Test1的文档集合;但是.Find(new BsonDocument())是查询集合中的所有文档,因此获取到 Test2。

但是 Test2 是不能转为 Test1 的,因此,会导致程序报错。

查看所有文档

var documents = collection1.Find(new BsonDocument()).ToList(); var documents = await collection1.Find(new BsonDocument()).ToListAsync();

前面已经说过,如果集合中存在其它格式的文档,获取全部文档时,因为 Test2 跟 Test1 没任何关系,会导致MongoDB.Driver报错。

如果文档数量比较大,要使用异步的ForEachAsync()查询,其原理是 回调。

List<Test1> tests = new List<Test1>(); Action<Test1> action = item => { tests.Add(item); Console.WriteLine(JsonSerializer.Serialize(item)); }; await collection1.Find(new BsonDocument()).ForEachAsync(action);

查询结束

使用Find()以及后续函数查询后,要结束查询(延迟加载),可以使用ToCursor()函数结束,程序会立即开始查询并将数据返回内存。

转换查询

使用ToEnumerable()可以使用 Linq 来查询文档。

var list = collection1.Find(new BsonDocument()).ToCursor().ToEnumerable();

过滤器

前面我们查询的时候都使用.Find(new BsonDocument())BsonDocument是过滤器对象,里面存储了过滤的规则,但是我们不能直接设置new BsonDocument()中的属性,而是使用构建器FilterDefinitionBuilder对象,而此对象可以通过MongoDB.Driver.Builders<TDocument>.Filter创建 。

假设有以下数据集(文档):

5f8bdf88e63d14cb5f01dd85 小明 19 5f8bdf88e63d14cb5f01dd86 小红 20 5f8bdf88e63d14cb5f01dd87 小张 16 5f8bdf88e63d14cb5f01dd88 小小 17 # -----插入数据的代码----- public class Test { public ObjectId _id { get; set; } public string Name { get; set; } public int Age { get; set; } } var datas = new Test[] { new Test{ Name="小明",Age=19}, new Test{ Name="小红",Age=20}, new Test{ Name="小张",Age=16}, new Test{ Name="小小",Age=17} }; collection.InsertMany(datas);

使用构建器:

FilterDefinition<Test> filter = Builders<Test>.Filter

查询 Age 大于 18 的文档:

FilterDefinition<Test> filter = filterBuilder.Where(item => item.Age >= 18);

获取结果:

Test[] documents = collection.Find(filter).ToEnumerable<Test>().ToArray();

过滤器还有Gt()In()Lte()等非 Linq 的函数,需要查看文档学习。

Builders<TDocument>

Builders<TDocument>除了能够生成过滤构建器,还有其它几种构建器:

// 条件过滤 public static FilterDefinitionBuilder<TDocument> Filter { get; } // 索引过滤 public static IndexKeysDefinitionBuilder<TDocument> IndexKeys { get; } // 映射器,相当于使用 Linq 的 .Select() 查询自己只需要的字段 public static ProjectionDefinitionBuilder<TDocument> Projection { get; } // 排序,创建排序规则,如工具年龄排序 public static SortDefinitionBuilder<TDocument> Sort { get; } // 更新,更新某些字段的值等 public static UpdateDefinitionBuilder<TDocument> Update { get; }

详细请参考mongodb.github.io/mongo-csharp-driver/2.10/reference/driver/definitions/#projections

名称映射

由于 MongoDB 区分字段的大小写,文档的字段一般使用驼峰命名法,首字母小写,而 C# 字段属性首字母是 大小开头的,因此需要不同名称对应起来。

可以使用BsonElement特性来设置映射的名称。

class Person { [BsonElement("fn")] public string FirstName { get; set; } [BsonElement("ln")] public string LastName { get; set; } }

以上就是 MongoDB 的初入门知识,但是使用了 MongoDB 有什么好处?可以参考这篇文章:www.jb51.net/article/238542.htm

整理场景如下:

  • 存储应用程序日志。日志结构化,查找方便,可以导出其它格式和二次利用。

  • 增加字段不需要改动表结构,灵活变更。

  • 支持 json 格式导入;类似 json 的数据结构;能够很容易还原对象的属性,一次性存储数据;如果使用传统数据库,则需要建立多个表并设置主键外界关系。

  • 集群。分布式集群海量数据,容易拓展;故障转移保证服务可用;

  • 解决分布式文件存储需求。

  • 索引方式灵活。

到此这篇关于MongoDB数据库介绍并用.NET Core对其进行编码的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持自由互联。

标签:对其

本文共计2955个文字,预计阅读时间需要12分钟。

如何使用.NET Core对MongoDB数据库进行编码以实现长尾词查询功能?

MongoDB 是一种 NoSQL 数据库,主要特征是存储结构化数据。它基于分布式文件存储,是一种开源数据库系统。与传统的 SQL 数据库(如 MySQL、SQL Server)不同,MongoDB 以文档形式存储数据,更适合处理大量非结构化或半结构化数据。

浅入 MongoDB

MonogoDB 是什么

MongoDB 是 NoSQL 型数据库,主要特征是存储结构化数据,MongoDB 是基于分布式文件存储的开源数据库系统。

结构化数据

以往我们使用 Mysql、SqlServer 等数据库,数据都是一条条的。MongoDB 的结构化数据正是区别于这种列-行式的数据。

结构化数据具有层级关系:

例如:

{ name: "MongoDB", type: "database", count: 1, info: { x: 203, y: 102 } }

MongoDB 与关系型数据库

由于 MongoDB 中,没有表、行、列,因此初学 MongoDB 时可能会有困扰,这里给出一些 MongoDB 与 普通SQL数据库对应的术语。

SQL术语/概念MongoDB术语/概念解释/说明databasedatabase数据库tablecollection数据库表/集合rowdocument数据记录行/文档columnfield数据字段/域indexindex索引table joins非关系型数据库,表与表之间没关系primary keyprimary key主键,MongoDB自动将_id字段设置为主键

资料来源:www.runoob.com/mongodb/mongodb-databases-documents-collections.html

MongoDB 入门命令

使用 mongo 进入 MongoDB shell 后,可使用命令(相当于SQL)执行操作。

注: MongoDB 中,有一个自动的 _id 字段,此字段 MongoDB 自动设置为主键并自动生成值。

显示所有数据库(包含系统数据库):

show dbs

当前正在操作的数据库或集合:

如何使用.NET Core对MongoDB数据库进行编码以实现长尾词查询功能?

db

连接到指定数据库:

use {数据库名称}

显示所有集合:

show collections # 或 show tables

查看集合中的所有文档:

# MyCollection 是集合名称 db.getCollection("MyCollection").find() db.getCollection("MyCollection").find().limit(1000).skip(0)

可能你不信,笔者百度了很久,第一页没找到一篇合适的友好的 "mongoDB 查看集合中的所有文档",特别是 CSDN 的垃圾文真的多。建议别瞎折腾了,去下一个 Navicat Premium,操作的时候,底部会提示所用的命令。

另外 MongoDB 有很多实用工具:docs.mongodb.com/tools/

文档

MongoDB 中的文档(Document)即关系型数据库中的一条记录(row)、一行数据。

但, MongoDB 中,一个集合(Collection-Table)中,是不需要具有相同字段的。例如:

A 文档:

{ name: "MongoDB", type: "database", count: 1, info: { x: 203, y: 102 } }

B 文档:

{ name: "MongoDB", typeName: "database", dataCount: 1, dataInfo: { m: 203, n: 102 } }

.NET Core 示例

我们从一个基础模板开始。

创建一个控制台程序,打开 Nuget 搜索并安装MongoDB.Driver

var client = new MongoClient("mongodb://{MongoDB}:27017"); IMongoDatabase database = client.GetDatabase("Test");

集合

可以通过CreateCollection()CreateCollectionAsync()创建一个集合,跟普通数据库不同的是,创建集合时是不需要指定结构的,只需要指定名称即可:

await database.CreateCollectionAsync("Test");

获取集合

GetCollection()函数可以让我们获取到集合,如果集合不存在,则会自动创建。

IMongoCollection<TDocument> GetCollection<TDocument>()

由于同一个集合可以有不同字段和字段类型的文档,因此几个文档如果有所差别,是很难统一起来的,例如:

(N/A) 代表此文档没有这个字段;如果一个文档有 10 个字段,另一个文档有 8 个字段,但是两者的字段完全不同时,要合并起来来,就有 18 个字段了。很明显,不应该汇集在一起,而是应该使用强类型对其 ”归档“ 。

创建两个类,分别为 Test1,Test2,其内容如下:

public class Test1 { public string Name { get; set; } } public class Test2 { public string DataType { get; set; } }

以两种文档类型获取集合:

var collection1 = database.GetCollection<Test1>("Test"); var collection2 = database.GetCollection<Test2>("Test");

这个获取集合的意思是,获取此集合中这类格式的文档的操作能力。

往集合中插入数据:

collection1.InsertOne(new Test1 { Name = "Test1" }); collection2.InsertOne(new Test2 { DataType = "Test2" }); // await collection.InsertOneAsync(object);

启动,查看结果。

InsertMany()可以插入批量数据:

Test1[] datas = new Test1[] { new Test1 { Name = "Test1" } }; collection1.InsertMany(datas);

统计数量

获取集合中所有的文档数:

collection1.CountDocuments(new BsonDocument()) // await collection1.CountDocumentsAsync(new BsonDocument());

任意一个文档集合对象,使用CountDocuments(new BsonDocument())都是获得此集合的所有文档数,而不是此类型的文档数。例如:

var collection1 = database.GetCollection<Test1>("Test"); collection1.CountDocuments(new BsonDocument())

获取的并不是 Test1 类型的文档数量,而是整个集合所有文档的数量。

原因是,CountDocuments()是一个过滤器函数,可以使用指定条件来筛选符合条件的文档的数量。指定条件后面会介绍。

查询

MongoDB 的查询并不像 LInq 中的表达式,基础了IEnumerableIEnumerable<T>接口,因此驱动没有WhereSelect这种表达式的查询方法。

Find()函数是查询函数,里面可以添加丰富的表达式,来筛选文档,当数据加载到本地内存后,即可使用丰富的表达式。

BsonDocument是一个类型,代表了要查询的文档筛选条件,如果BsonDocument对象没有添加任何属性,则代码没有筛选参数,则默认所有文档都符号条件。

我们把 Test1 和 Test2 类型,都加上一个属性:

public ObjectId _id { get; set; }

不然会报格式化错误:System.FormatException

如何序列化文档

document是文档对象, JsonSerializer 是 System.Text.Json 的静态类。

Console.WriteLine(JsonSerializer.Serialize(document));

查询第一条记录

var document = collection1.Find(new BsonDocument()).FirstOrDefault();

不加条件可能导致的问题

以下代码会导致程序报错:

var documents = await collection1.Find(new BsonDocument()).ToListAsync(); foreach(var item in documents) { Console.WriteLine(JsonSerializer.Serialize(item)); }

因为collection1是标记为Test1的文档集合;但是.Find(new BsonDocument())是查询集合中的所有文档,因此获取到 Test2。

但是 Test2 是不能转为 Test1 的,因此,会导致程序报错。

查看所有文档

var documents = collection1.Find(new BsonDocument()).ToList(); var documents = await collection1.Find(new BsonDocument()).ToListAsync();

前面已经说过,如果集合中存在其它格式的文档,获取全部文档时,因为 Test2 跟 Test1 没任何关系,会导致MongoDB.Driver报错。

如果文档数量比较大,要使用异步的ForEachAsync()查询,其原理是 回调。

List<Test1> tests = new List<Test1>(); Action<Test1> action = item => { tests.Add(item); Console.WriteLine(JsonSerializer.Serialize(item)); }; await collection1.Find(new BsonDocument()).ForEachAsync(action);

查询结束

使用Find()以及后续函数查询后,要结束查询(延迟加载),可以使用ToCursor()函数结束,程序会立即开始查询并将数据返回内存。

转换查询

使用ToEnumerable()可以使用 Linq 来查询文档。

var list = collection1.Find(new BsonDocument()).ToCursor().ToEnumerable();

过滤器

前面我们查询的时候都使用.Find(new BsonDocument())BsonDocument是过滤器对象,里面存储了过滤的规则,但是我们不能直接设置new BsonDocument()中的属性,而是使用构建器FilterDefinitionBuilder对象,而此对象可以通过MongoDB.Driver.Builders<TDocument>.Filter创建 。

假设有以下数据集(文档):

5f8bdf88e63d14cb5f01dd85 小明 19 5f8bdf88e63d14cb5f01dd86 小红 20 5f8bdf88e63d14cb5f01dd87 小张 16 5f8bdf88e63d14cb5f01dd88 小小 17 # -----插入数据的代码----- public class Test { public ObjectId _id { get; set; } public string Name { get; set; } public int Age { get; set; } } var datas = new Test[] { new Test{ Name="小明",Age=19}, new Test{ Name="小红",Age=20}, new Test{ Name="小张",Age=16}, new Test{ Name="小小",Age=17} }; collection.InsertMany(datas);

使用构建器:

FilterDefinition<Test> filter = Builders<Test>.Filter

查询 Age 大于 18 的文档:

FilterDefinition<Test> filter = filterBuilder.Where(item => item.Age >= 18);

获取结果:

Test[] documents = collection.Find(filter).ToEnumerable<Test>().ToArray();

过滤器还有Gt()In()Lte()等非 Linq 的函数,需要查看文档学习。

Builders<TDocument>

Builders<TDocument>除了能够生成过滤构建器,还有其它几种构建器:

// 条件过滤 public static FilterDefinitionBuilder<TDocument> Filter { get; } // 索引过滤 public static IndexKeysDefinitionBuilder<TDocument> IndexKeys { get; } // 映射器,相当于使用 Linq 的 .Select() 查询自己只需要的字段 public static ProjectionDefinitionBuilder<TDocument> Projection { get; } // 排序,创建排序规则,如工具年龄排序 public static SortDefinitionBuilder<TDocument> Sort { get; } // 更新,更新某些字段的值等 public static UpdateDefinitionBuilder<TDocument> Update { get; }

详细请参考mongodb.github.io/mongo-csharp-driver/2.10/reference/driver/definitions/#projections

名称映射

由于 MongoDB 区分字段的大小写,文档的字段一般使用驼峰命名法,首字母小写,而 C# 字段属性首字母是 大小开头的,因此需要不同名称对应起来。

可以使用BsonElement特性来设置映射的名称。

class Person { [BsonElement("fn")] public string FirstName { get; set; } [BsonElement("ln")] public string LastName { get; set; } }

以上就是 MongoDB 的初入门知识,但是使用了 MongoDB 有什么好处?可以参考这篇文章:www.jb51.net/article/238542.htm

整理场景如下:

  • 存储应用程序日志。日志结构化,查找方便,可以导出其它格式和二次利用。

  • 增加字段不需要改动表结构,灵活变更。

  • 支持 json 格式导入;类似 json 的数据结构;能够很容易还原对象的属性,一次性存储数据;如果使用传统数据库,则需要建立多个表并设置主键外界关系。

  • 集群。分布式集群海量数据,容易拓展;故障转移保证服务可用;

  • 解决分布式文件存储需求。

  • 索引方式灵活。

到此这篇关于MongoDB数据库介绍并用.NET Core对其进行编码的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持自由互联。

标签:对其