【问题标题】:How do I describe a collection in Mongo?如何在 Mongo 中描述一个集合?
【发布时间】:2011-06-13 22:06:20
【问题描述】:

所以这是学习 Mongo Db 的第 3 天。我来自 MySql 世界...

很多时候,当我需要为我不熟悉的 MySql 表编写查询时,我会使用“desc”命令 - 主要是告诉我应该在查询中包含哪些字段。

我将如何为 Mongo 数据库执行此操作?我知道,我知道...我正在无模式数据库中搜索模式。 =) 但是用户怎么知道在他们的查询中使用哪些字段呢?

我是不是走错路了?显然,我正在尝试在 Mongo db 中使用 MySql 做事方式。什么是蒙古方式?

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    在编辑器/mongoshell 中输入以下查询

    var col_list= db.emp.findOne();
    for (var col in col_list) { print (col) ; }
    

    输出将为您提供集合中列的名称:

    _id
    name
    salary
    

    【讨论】:

    • 我喜欢这种方法。它不一定给出集合中所有文档的结构,但它至少可以开始数据库探索。
    【解决方案2】:

    这里没有好的答案。因为没有模式,所以您不能“描述”集合。然而,在许多(大多数?)MongoDb 应用程序中,模式是由编写应用程序(java 或 c# 或其他)中使用的对象层次结构的结构定义的,因此您可以反映对象库以获取该信息.否则会有一些尝试和错误。

    【讨论】:

    • 此外,在给定的集合中也没有强制执行一致的文档结构,因此您真的无法描述它,因为您查询的数据可能因文档而异。
    【解决方案3】:

    这是我第 30 天,或者类似于玩 MongoDB 的一天。不幸的是,由于我公司当前的基础设施问题,我们在使用 MongoDB 之后又切换回 MySQL。但是在 MongoDB 和 MySQL 上实现了相同的模型后,我现在可以清楚地看到差异。

    当然,在处理像 MongoDB 这样的无模式数据库时会涉及到模式,但模式是由应用程序决定的,而不是由数据库决定的。数据库将推入给定的任何内容。只要您知道管理员没有秘密登录 Mongo 并进行更改,并且所有对数据库的访问都是通过某些 wrapper 的控制器,那么您应该查看模式的唯一地方就是您的模型类。例如,在我们的 Rails 应用程序中,这是我们在 Mongo 中的两个模型,

    class Consumer
        include MongoMapper::Document
    
        key :name, String
        key :phone_number, String
        one :address
    end
    
    class Address
        include MongoMapper::EmbeddedDocument
    
        key :street, String
        key :city, String
        key :state, String
        key :zip, String
        key :state, String
        key :country, String
    end
    

    现在切换到 MySQL 后,我们的类是这样的,

    class Consumer < ActiveRecord::Base
        has_one :address
    end
    
    class Address < ActiveRecord::Base
        belongs_to :consumer
    end
    

    不要被课程的简洁性所迷惑。在 MySQL 的后一个版本中,字段是直接从数据库中提取的。在前一个示例中,字段就在我们眼前。

    使用 MongoDB,如果我们必须更改特定模型,我们只需添加、删除或修改类本身的字段,它就可以立即工作。我们不必担心保持数据库表/列与类结构同步。因此,如果您在 MongoDB 中寻找架构,请在您的应用程序中寻找答案,而不是数据库。

    基本上我说的和@Chris Shain 完全一样:)

    【讨论】:

    • 我认为我更喜欢将架构保留为代码,因为它更明确且受版本控制。
    【解决方案4】:

    我也有这种需要,Cavachon。所以我创建了一个名为 Variety 的开源工具,它正是这样做的:link

    希望您会发现它很有用。如果您有任何问题或使用它的任何问题,请告诉我。

    祝你好运!

    【讨论】:

      【解决方案5】:

      虽然事实上是正确的,但你们都把它弄得太复杂了。我认为 OP 只是想知道他/她的数据是什么样的。如果是这样的话,你就可以了

      db.collectionName.findOne()
      

      这将以漂亮的格式显示数据库中的一个文档(又名记录)。

      【讨论】:

      • 您不能将pretty()findOne() 一起使用。 pretty() 是一种游标方法,不适用于findOne(),因为它不返回游标。只需使用findOne() 即可为您格式化输出。
      • 警告:这仅适用于存在集合数据的情况,如db.collectionName.count() &gt; 0。如果集合为空 - 其中db.collectionName.count() === 0,则不会描述集合。
      • 当然,对于 NoSQL 数据库,当没有数据时,没有什么可“描述”的!
      【解决方案6】:

      AFAIK,没有办法,这样做是合乎逻辑的。

      MongoDB 是无模式的,允许单个集合拥有具有不同字段的文档。所以实际上不可能有一个集合的描述,就像关系数据库中的一个表的描述。

      虽然是这种情况,但大多数应用程序确实为其集合维护了一个架构,正如 Chris 所说,这是由您的应用程序强制执行的。

      因此,您不必担心首先获取可用键来进行查询。您可以只向 MongoDB 询问任何一组键(即查询的投影部分)或查询任何一组键。在这两种情况下,如果指定的键存在于文档中,则使用它们,否则不使用。你不会得到任何错误。

      例如(在 mongo shell 上):

      如果这是您的 people 集合中的示例文档并且所有文档都遵循相同的架构:

      {
        name : "My Name"
        place : "My Place"
        city : "My City"
      }
      

      以下是完全有效的查询:

      这两个会返回上面的文档:

      db.people.find({name : "My Name"})
      db.people.find({name : "My Name"}, {name : 1, place :1})
      

      这不会返回任何东西,但也不会引发错误:

      db.people.find({first_name : "My Name"})
      

      这将匹配上面的文档,但返回的文档只有默认的“_id”属性。

      db.people.find({name : "My Name"}, {first_name : 1, location :1})
      

      【讨论】:

        【解决方案7】:
        print('\n--->', Object.getOwnPropertyNames(db.users.findOne())
          .toString()
          .replace(/,/g, '\n---> ') + '\n');
        

        ---> _id
        ---> firstName
        ---> lastName
        ---> email
        ---> password
        ---> terms
        ---> confirmed
        ---> userAgent
        ---> createdAt
        

        【讨论】:

        • 有没有办法添加类型?
        【解决方案8】:

        这是一个不完整的解决方案,因为它没有为您提供确切的类型,但对于快速查看很有用。

        const doc = db.collectionName.findOne();
        for (x in doc) {
          print(`${x}: ${typeof doc[x]}`)
        };
        

        【讨论】:

          【解决方案9】:

          如果您可以运行 Map/Reduce,您可以收集所有可能的文档字段。

          this post开头。

          这里唯一的问题是您运行的 Map / Reduce 可能会占用大量资源。相反,正如其他人所建议的那样,您需要查看写入实际数据的代码。

          仅仅因为数据库没有架构并不意味着没有架构。一般来说,架构信息会在代码中。

          【讨论】:

            【解决方案10】:

            我写了一个小 mongo shell 脚本,可以帮助你。 https://gist.github.com/hkasera/9386709

            如果有帮助,请告诉我。

            【讨论】:

              【解决方案11】:

              您可以使用 mongoDb 的 UI 工具 mongo compass。这显示了该集合中的所有字段,还显示了其中数据的变化。

              【讨论】:

                【解决方案12】:

                如果您使用 NodeJS 并希望使用 API 请求获取所有字段名称,则此代码适用于我-

                let arrayResult = [];
                
                db.findOne().exec(function (err, docs)){
                 if(err)
                  //show error
                
                  const JSONobj = JSON.parse(JSON.stringify(docs));
                     for(let key in JSONobj) {
                       arrayResult.push(key);
                     }
                  return callback(null, arrayResult);
                }
                

                arrayResult 将为您提供整个字段/列名称

                输出-

                [
                 "_id",
                 "emp_id",
                 "emp_type",
                 "emp_status",
                 "emp_payment"
                ]
                

                希望这对你有用!

                【讨论】:

                  【解决方案13】:

                  假设您有一个名为 people 的集合,并且您想要查找字段及其数据类型。您可以使用以下查询

                  function printSchema(obj) {
                      for (var key in obj) {
                          print( key, typeof obj[key]) ;
                      }
                  };
                  
                  var obj = db.people.findOne();
                  printSchema(obj)
                  

                  此查询的结果将如下所示,

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2015-07-03
                    • 2018-02-24
                    • 1970-01-01
                    • 2022-01-05
                    • 1970-01-01
                    • 2020-07-22
                    • 2016-07-20
                    • 1970-01-01
                    相关资源
                    最近更新 更多