【问题标题】:How get all keys in all level in a mongo collection c#? LinQ Functions如何在 mongo 集合 c# 中获取所有级别的所有键? LinQ 函数
【发布时间】:2022-08-16 01:58:04
【问题描述】:

我正在尝试获取 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\"]

我的代码有什么问题?

  • 据我所知,你没有做你期望做的事。 FirstOrDefault 只是从您的收藏中获取第一条记录(即只应用limit(1) 选项)。这里没有更多的逻辑。我仍然不太了解您想要做什么,但是正如我所见,您需要一个完整的文档,然后以某种方式对其进行分析。然后只需使用 BsonDocument 而不是动态的。然后分析这个文件,考虑结构为json。

标签: c# mongodb visual-studio linq studio3t


【解决方案1】:

@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();
      }
      

      Sample .NET Fiddle

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-18
    • 2011-11-19
    相关资源
    最近更新 更多