使用 FSharp 获取有关 MongoDB 集合的一般信息
问题:使用 FSharp 获取有关 MongoDB 集合的一般信息 我可以用F#检索MongoDB中所有集合的基本信息吗? 我有一个拥有 > 450 个集合的MongoDB。我可以访问数据库 open MongoDB.Bson open MongoDB.Driver open MongoDB.Driver.Core open MongoDB.FSharp open System.Collectio
问题:使用 FSharp 获取有关 MongoDB 集合的一般信息
我可以用F#
检索MongoDB
中所有集合的基本信息吗?
我有一个拥有 > 450 个集合的MongoDB
。我可以访问数据库
open MongoDB.Bson
open MongoDB.Driver
open MongoDB.Driver.Core
open MongoDB.FSharp
open System.Collections.Generic
let connectionString = "mystring"
let client = new MongoClient(connectionString)
let db = client.GetDatabase(name = "Production")
我曾考虑尝试仅获取所有集合,然后遍历每个集合名称并获取有关每个集合的基本信息
let collections = db.ListCollections()
和
db.GetCollection([name of a collection])
但是db.GetCollection([name])
要求我定义一个类型来提取有关每个集合的信息。这对我来说很有挑战性,因为我不想为每个集合定义一个类型,其中有 > 450,坦率地说,我对这个数据库了解不多。 (实际上,我的组织中没有人这样做;这就是为什么我试图将一个_非常基本的_数据字典放在一起。)
为每个集合定义类型真的有必要吗?我可以使用此处提供的MongoCollection 方法而不必为每个集合定义类型吗?
编辑:最终,我希望能够输出集合名称、每个集合中的 n 个文档、每个集合中的字段名称列表以及每个字段类型的列表。
解答
我选择用 C# 编写示例,因为我更熟悉 C# 驱动程序,并且它是问题中列出的标记。您可以对每个集合运行聚合以查找每个文档的所有顶级字段及其(mongodb)类型。
聚合分 3 个步骤完成。让我们假设输入是 10 个文档,它们都具有这种形式:
{
"_id": ObjectId("myId"),
"num": 1,
"str": "Hello, world!"
}
1.$project
将每个文档转换成一个文档数组,其值为fieldName
和fieldType
。输出 10 个具有单个数组字段的文档。数组字段将有 3 个元素。
2.$unwind
字段信息数组。输出 30 个文档,每个文档都有一个字段,对应于步骤 1 的输出中的一个元素。
3.$group
字段通过fieldName
和fieldType
得到不同的值。输出 3 个文件。由于在本例中所有同名的字段总是具有相同的类型,因此每个字段只有一个最终输出文档。如果两个不同的文档定义了相同的字段,一个作为字符串,一个作为 int,则此结果集中将有两个单独的条目。
// Define our aggregation steps.
// Step 1, $project:
var project = new BsonDocument
{ {
"$project", new BsonDocument
{
{
"_id", 0
},
{
"fields", new BsonDocument
{ {
"$map", new BsonDocument
{
{ "input", new BsonDocument { { "$objectToArray", "$$ROOT" } } },
{ "in", new BsonDocument {
{ "fieldName", "$$this.k" },
{ "fieldType", new BsonDocument { { "$type", "$$this.v" } } }
} }
}
} }
}
}
} };
// Step 2, $unwind
var unwind = new BsonDocument
{ {
"$unwind", "$fields"
} };
// Step 3, $group
var group = new BsonDocument
{
{
"$group", new BsonDocument
{
{
"_id", new BsonDocument
{
{ "fieldName", "$fields.fieldName" },
{ "fieldType", "$fields.fieldType" }
}
}
}
}
};
// Connect to our database
var client = new MongoClient("myConnectionString");
var db = client.GetDatabase("myDatabase");
var collections = db.ListCollections().ToEnumerable();
/*
We will store the results in a dictionary of collections.
Since the same field can have multiple types associated with it the inner value corresponding to each field is `List<string>`.
The outer dictionary keys are collection names. The inner dictionary keys are field names.
The inner dictionary values are the types for the provided inner dictionary's key (field name).
List<string> fieldTypes = allCollectionFieldTypes[collectionName][fieldName]
*/
Dictionary<string, Dictionary<string, List<string>>> allCollectionFieldTypes = new Dictionary<string, Dictionary<string, List<string>>>();
foreach (var collInfo in collections)
{
var collName = collInfo["name"].AsString;
var coll = db.GetCollection<BsonDocument>(collName);
Console.WriteLine("Finding field information for " + collName);
var pipeline = PipelineDefinition<BsonDocument, BsonDocument>.Create(project, unwind, group);
var cursor = coll.Aggregate(pipeline);
var lst = cursor.ToList();
allCollectionFieldTypes.Add(collName, new Dictionary<string, List<string>>());
foreach (var item in lst)
{
var innerDict = allCollectionFieldTypes[collName];
var fieldName = item["_id"]["fieldName"].AsString;
var fieldType = item["_id"]["fieldType"].AsString;
if (!innerDict.ContainsKey(fieldName))
{
innerDict.Add(fieldName, new List<string>());
}
innerDict[fieldName].Add(fieldType);
}
}
现在您可以迭代您的结果集:
foreach(var collKvp in allCollectionFieldTypes)
{
foreach(var fieldKvp in collKvp.Value)
{
foreach(var fieldType in fieldKvp.Value)
{
Console.WriteLine($"Collection {collKvp.Key} has field name {fieldKvp.Key} with type {fieldType}");
}
}
}
更多推荐
所有评论(0)