我想对Mongodb数据库进行 partial 转储( partial ,因为我需要过滤一些文档和一些字段)。然后,此转储将导入到另一台服务器上。
我不能使用 mongodump 实用程序,因为它不允许过滤字段。
我可以使用 mongoexport 实用程序,因为它可以同时过滤文档和字段。不过,文档指出 mongoexport 只能输出JSON文件,并且:
不能可靠地保留所有丰富的BSON数据类型,因为JSON只能表示BSON支持的类型的子集。
答案 0 :(得分:3)
可以使用Views进行操作,而不必诉诸于编写读写BSON内容的底层实现。实际上,即使使用JSON格式,也有一些选项保留类型,并且您甚至不需要“查看”。
mongodump
使用视图基本前提是创建一个只返回所需内容的视图。一个View可以是任何聚合管道表达式的结果。
例如,给定集合中的一个简单文档:
db.test.insert({ "a": 1, "b": 2, "c": 3 })
您可以在该集合上创建带有仅所需字段的视图:
db.test.createView("testView", "test", [{ "$project": { "a": 1, "b": 2 } }])
然后退出mongo shell,您可以使用mongodump
选项从--viewsAsCollections
访问视图:
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
语句可以进行过滤,您可以随意转换甚至“聚合”。
--fields
与mongoexport
一起使用与mongoexport
实用程序大致相同,它也可以从视图中访问内容。
尽管这不是“严格BSON” ,但实际上MongoDB有一个标准,它实际上保留数据类型。实际上,MongoDB extended JSON下的文档中对此进行了介绍。
所以这不是二进制格式,并且作为JSON,它确实占用了更多的存储空间,但确实存在必要的信息。
例如:
db.mixed.insert({
"a": NumberLong(1),
"b": NumberDecimal("123.45"),
"c": new Date(),
"d": "unwanted"
})
在mongo
外壳中显示为:
{
"_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
识别,并且还有许多语言都可以使用的解析器实现,这些解析器也可以识别这种格式,并且在读取内容时,它会与保留“类型” 信息:
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")
}
因此,在发送 binary 内容可能不可行甚至不希望发送但保持的情况下,有可能存在Extended JSON格式以用于数据交换。类型” 信息是可取的。
总体上,您可以使用许多选项,而无需恢复读写二进制BSON格式,或任何其他复杂的二进制格式来存储两次传输之间的数据。
作为“模糊” 段落的注释,在文档的Extended JSON页中列出了实际支持的BSON类型。您甚至可以将其与BSON Specification进行比较,以了解尽管有“谨慎” 语句,但实际上确实支持您将要使用的 common 类型的数据。尽管对该规范的一些外部解释可能并不坚持理解它们的 ALL ,但捆绑的实用程序(例如mongoexport
和mongoimport
确实是合规的。