我正在尝试获取Mongo集合的所有级别中的所有密钥。我有这样的东西:
{
"_id" : ObjectId("000000000000000000050904"),
"CRM" : {
"Teste" : "true"
},
"Endereco" : {
"Cidade" : "MARINGA",
},
"Vendas" : [
{
"idP" : NumberInt(34),
"txt" : "001"
},{
"idP" : NumberInt(34),
"txt" : "002"
}
],
"Tipos" : [
{
"idT" : NumberInt(34),
"idTipo" : NumberInt(34)
},{
"idT" : NumberInt(34),
"idTipo" : NumberInt(34)
}
]
}
我试过了:
var database = _mongoDatabase.Client.GetDatabase(_project.DbConfig.Database);
var collection = database.GetCollection<dynamic>(collectionName);
var query = collection.AsQueryable<dynamic>();
IDictionary<string, string> myDict = (IDictionary<string, string>)query.FirstOrDefault();
List<string> collectionKeys = new List<string>(myDict.Keys.ToList());
我得到:
["CRM", "Teste", "Endereco", "Cidade", "Vendas", "Tipos"]
但我想要所有级别:
["CRM", "Teste", "Endereco", "Cidade", "Vendas", "IdP", "txt", "Tipos", "idT", "idTipo"]
我的代码出了什么问题?
@dododo已经指明了方向,您需要BsonDocument
而不是dynamic
。
实现逻辑应用了递归函数的概念,在递归函数中,您的数据可能具有嵌套文档、具有(嵌套(文档的数组,甚至具有嵌套数组。
GetDocumentKeys
:
-
当它是
null
时,返回一个空数组。 -
如果不是
BsonDocument
,则返回一个空数组。 -
迭代
BsonDocument
中的每个属性,将Name
添加到数组中,并递归调用GetDocumentKeys
和GetArrayKeys
函数。
GetArrayKeys
:
-
当它是
null
时,返回一个空数组。 -
如果不是
BsonArray
,则返回一个空数组。 -
对
BsonArray
中的每个元素进行迭代,递归调用GetDocumentKeys
和GetArrayKeys
函数。
private List<string> GetDocumentKeys(BsonValue value)
{
List<string> keys = new List<string>();
if (value == null)
return keys;
if (value.GetType() != typeof(BsonDocument))
return keys;
foreach (var kvp in (BsonDocument)value)
{
keys.Add(kvp.Name);
keys.AddRange(GetArrayKeys(kvp.Value));
keys.AddRange(GetDocumentKeys(kvp.Value));
}
return keys;
}
private List<string> GetArrayKeys(BsonValue value)
{
List<string> keys = new List<string>();
if (value == null)
return keys;
if (value.GetType() != typeof(BsonArray))
return keys;
foreach (var item in (BsonArray)value)
{
keys.AddRange(GetArrayKeys(item));
keys.AddRange(GetDocumentKeys(item));
}
return keys;
}
假设您只处理一个文档
呼叫方功能:
using MongoDB.Bson;
using System.Collections.Generic;
using System.Linq;
var collection = database.GetCollection<BsonDocument>(collectionName);
var query = collection.AsQueryable<BsonDocument>();
BsonDocument bson = query.FirstOrDefault();
List<string> collectionKeys = GetRootDocumentAllKeys(bson);
private List<string> GetRootDocumentAllKeys(BsonDocument bson)
{
List<string> collectionKeys = new List<string>();
collectionKeys.AddRange(GetDocumentKeys(bson));
return collectionKeys.Distinct()
.ToList();
}
.NET Fiddle 示例