Mongodb dump(过滤文档和字段)

Mik*_*esi 5 dump filter mongodb bson mongoexport

我想打一个局部MongoDB数据库的转储(部分为,我需要过滤掉一些文件,有些领域)。然后,此转储将导入到另一台服务器上。

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

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

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

Nei*_*unn 9

可以使用视图来实现,而无需编写低级实现来读取和写入 BSON 内容。实际上,即使使用 JSON 格式,也有一些选项可以保留类型,并且您甚至不需要为此使用“视图”。

使用视图mongodump

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

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

db.test.insert({ "a": 1, "b": 2, "c": 3 })
Run Code Online (Sandbox Code Playgroud)

您可以使用所需的字段在该集合上创建视图:

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

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

mongodump --db test --collection testView --viewsAsCollections
Run Code Online (Sandbox Code Playgroud)

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

然后可以通过以下方式加载生成的 BSON 内容mongorestore

mongorestore --db other --collection test
Run Code Online (Sandbox Code Playgroud)

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

use other
db.test.find()

{ "_id" : ObjectId("5bfb3e0eadd1d8af906ad140"), "a" : 1, "b" : 2 }
Run Code Online (Sandbox Code Playgroud)

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

使用视图或--fieldsmongoexport

以大致相同的方式,该mongoexport实用程序还可以从视图访问内容。

尽管这不是“严格的 BSON”,但实际上 MongoDB 有一个标准,它确实保留了数据类型。这实际上在MongoDB 扩展 JSON下的文档中有介绍。

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

例如:

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

在 shell 中将显示mongo为:

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

您仍然可以设置视图:

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

导出只会获取数据:

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"
        }
}
Run Code Online (Sandbox Code Playgroud)

或者原始集合上的相同内容,仅用于--fields选择:

mongoexport --db test --collection mixed --fields a,b,c > out.json
Run Code Online (Sandbox Code Playgroud)

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

扩展JSON格式可以被识别mongoimport,并且还有可用于许多语言的解析器实现也可以识别这种格式,并且在读取内容时,它会被插入到目标集合中,并保留“类型”信息:

mongoimport --db other --collection mixed out.json
Run Code Online (Sandbox Code Playgroud)

然后查看数据:

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

因此,在发送二进制内容可能不可行或什至不理想的情况下,扩展 JSON格式的存在是为了数据交换的目的,但保留“类型”信息是理想的


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

作为“模糊”段落的注释,实际支持的 BSON 类型列在文档的扩展 JSON页面中。您甚至可以将其与BSON 规范进行比较,看看尽管有“谨慎”的声明,但您确实要使用的常见数据类型实际上都受支持。虽然该规范的一些外部解释可能无法理解所有这些规范,但捆绑的实用程序(例如mongoexport和 )mongoimport确实符合要求。