MongoDB LINQ-如何获取集合中所有级别的所有密钥



我正在尝试获取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:

  1. 当它是null时,返回一个空数组。

  2. 如果不是BsonDocument,则返回一个空数组。

  3. 迭代BsonDocument中的每个属性,将Name添加到数组中,并递归调用GetDocumentKeysGetArrayKeys函数。

GetArrayKeys:

  1. 当它是null时,返回一个空数组。

  2. 如果不是BsonArray,则返回一个空数组。

  3. BsonArray中的每个元素进行迭代,递归调用GetDocumentKeysGetArrayKeys函数。

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 示例

最新更新