【问题标题】:Mongodb dump (filtering documents and fields)Mongodb转储(过滤文档和字段)
【发布时间】:2018-11-26 15:09:13
【问题描述】:

我想对 Mongodb 数据库进行 部分 转储(部分,我需要过滤一些 文档 和一些 字段)。然后,这个转储将被导入到另一台服务器上。

我无法使用 mongodump 实用程序,因为它不允许过滤字段。
我可以使用 mongoexport 实用程序,因为它允许过滤文档和字段。不过,文档指出 mongoexport 只能输出 JSON 文件,并且:

不能可靠地保留所有丰富的 BSON 数据类型,因为 JSON 只能表示 BSON 支持的类型的子集。

  1. 我觉得这句话有点含糊,我并不完全理解。那么,如果我将数据库转储为 JSON,会发生什么?我要冒什么风险?我是否有丢失一些文件的风险?
  2. 如果您认为我应该绝对避免在生产中使用 mongoexport,我可以编写自己的 Nodejs 应用程序来执行过滤并在 BSON 中输出转储吗?或者那不可能?

【问题讨论】:

    标签: mongodb filter dump bson mongoexport


    【解决方案1】:

    可以使用Views 来完成,而无需编写读取和写入 BSON 内容的低级实现。还有一些选项实际上保留类型,即使在使用 JSON 格式时,您甚至不需要“视图”。

    使用带有mongodump 的视图

    基本前提是创建一个只返回你想要的内容的视图。视图可以是任何聚合管道表达式的结果。

    例如,给定一个集合中的简单文档:

    db.test.insert({ "a": 1, "b": 2, "c": 3 })
    

    您可以在该集合上创建视图,只需要需要的字段:

    db.test.createView("testView", "test", [{ "$project": { "a": 1, "b": 2 } }])
    

    然后退出 mongo shell,您可以使用 --viewsAsCollections 选项从 mongodump 访问视图:

    mongodump --db test --collection testView --viewsAsCollections
    

    这仅导出命名的 "collection" (实际上是一个 View )。 --viewsAsCollections 意味着 mongodump 不只是返回视图定义(本质上是聚合管道),而是返回结果,就像它是一个真正的集合一样。

    然后可以通过mongorestore 加载生成的 BSON 内容:

    mongorestore --db other --collection test
    

    然后来自 BSON 转储的内容实际上被写入您正在连接的主机的新数据库目标中,并具有指定的集合名称

    use other
    db.test.find()
    
    { "_id" : ObjectId("5bfb3e0eadd1d8af906ad140"), "a" : 1, "b" : 2 }
    

    还要注意,作为 View,聚合管道实际上可以是任何东西,因此 $match 语句可以过滤,您可以根据需要转换甚至实际“聚合”。

    使用视图或 --fieldsmongoexport

    同样,mongoexport 实用程序也可以访问视图中的内容。

    尽管这不是“严格的 BSON”,但实际上 MongoDB 有一个标准保留数据类型。这实际上包含在MongoDB extended JSON 下的文档中。

    所以这不是二进制格式,作为 JSON,它确实需要更多的存储空间,但确实存在必要的信息。

    例如:

    db.mixed.insert({
      "a": NumberLong(1),
      "b": NumberDecimal("123.45"),
      "c": new Date(),
      "d":  "unwanted"
    })
    

    mongo shell 中显示为:

    {
            "_id" : ObjectId("5bfb428790b2b4e4241a015c"),
            "a" : NumberLong(1),
            "b" : NumberDecimal("123.45"),
            "c" : ISODate("2018-11-26T00:47:03.033Z"),
            "d" : "unwanted"
    }
    

    您仍然可以设置视图:

    db.createView("mixedView", "mixed", [{ "$project": { "a": 1, "b": 1, "c": 1 } }])
    

    而导出只会获取数据:

    mongoexport --db test --collection mixedView > out.json
    
    {
            "_id": {
                    "$oid": "5bfb428790b2b4e4241a015c"
            },
            "a": {
                    "$numberLong": "1"
            },
            "b": {
                    "$numberDecimal": "123.45"
            },
            "c": {
                    "$date": "2018-11-26T00:47:03.033Z"
            }
    }
    

    或者在原来的集合上也一样,只是使用--fields进行选择:

    mongoexport --db test --collection mixed --fields a,b,c > out.json
    

    输出完全相同。唯一的限制是--query 只能支持find() 或类似的正则查询表达式。这不如View 灵活,但可以针对大多数需求进行基本过滤。

    Extended JSON 格式被 mongoimport 识别,并且还有许多语言的解析器实现也可以识别这一点,并且在读取内容时,它会被插入到带有 的目标集合中type" 保留信息:

    mongoimport --db other --collection mixed out.json
    

    然后查看数据:

    use other
    db.mixed.findOne()
    {
            "_id" : ObjectId("5bfb428790b2b4e4241a015c"),
            "a" : NumberLong(1),
            "b" : NumberDecimal("123.45"),
            "c" : ISODate("2018-11-26T00:47:03.033Z")
    }
    

    因此,Extended JSON 格式的存在是为了在发送 二进制 内容可能不可行甚至不希望但保持 “类型”的情况下进行数据交换信息是可取的


    总体而言,您可以使用许多选项,而无需恢复为读写二进制 BSON 格式或任何其他复杂的二进制格式来存储传输之间的数据。

    作为对 “模糊” 段落的注释,实际支持的 BSON 类型列在文档的 Extended JSON 页面中。您甚至可以将其与BSON Specification 进行比较,以发现尽管有 "cautious" 声明,但您确实会使用的 common 类型的数据实际上都支持。虽然一些对该规范的外部解释可能不符合理解所有它们,但捆绑的实用程序,如mongoexportmongoimport确实是合规的。

    【讨论】:

    • 感谢您的详细解释。所以,如果我错了,请纠正我,但我的第一个问题的答案是不,我不会通过使用 JSON 丢失任何信息,因为正如你所说“这不是二进制格式,并且作为 JSON它确实需要更多的存储空间,但确实存在必要的信息”。这意味着 JSON 转储文件包含完全相同的信息,但它通过占用更多空间对其进行编码。所以我可以期待一个 JSON 转储文件比它的 BSON 等效转储文件大,对吧?
    • 至于我的第二个问题:是否可以编写我自己的 Nodejs 应用程序来进行过滤并在 BSON 中输出转储文件?
    • 现在我将使用您的解决方案(即创建一个视图,然后使用 mongodump 转储它),但我仍然想知道是否可以使用一个自定义的 Nodejs 应用程序。原因是性能在我的场景中很重要,我感觉创建视图并随后使用 mongodump 转储它比执行过滤数据和过滤数据的 Nodejs 应用程序花费的时间要长得多。自动将其写入 (BSON) 转储文件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-16
    • 2019-07-11
    • 2020-02-18
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多