Mongodb转储(筛选文档和字段)
我想对Mongodb数据库进行部分转储(部分如中所示,我需要过滤一些文档和一些字段)。然后,此转储将导入到另一台服务器上 我无法使用mongodump实用程序,因为它不允许筛选字段。Mongodb转储(筛选文档和字段),mongodb,filter,dump,bson,mongoexport,Mongodb,Filter,Dump,Bson,Mongoexport,我想对Mongodb数据库进行部分转储(部分如中所示,我需要过滤一些文档和一些字段)。然后,此转储将导入到另一台服务器上 我无法使用mongodump实用程序,因为它不允许筛选字段。 我可以使用mongoexport实用程序,因为它可以过滤文档和字段。但是,文档说明mongoexport只能输出JSON文件,并且: 无法可靠地保留所有丰富的BSON数据类型,因为JSON只能表示BSON支持的类型的子集 我觉得这句话有点含糊,我不完全理解。那么,如果我用JSON转储数据库,会发生什么呢?我要冒什么
我可以使用mongoexport实用程序,因为它可以过滤文档和字段。但是,文档说明mongoexport只能输出JSON文件,并且: 无法可靠地保留所有丰富的BSON数据类型,因为JSON只能表示BSON支持的类型的子集
可以使用,而无需编写底层实现来读取和编写BSON内容。甚至在使用JSON格式时,也有一些选项实际上保留了类型,而您甚至不需要一个“视图” 与
mongodump一起使用视图
基本前提是创建一个只返回所需内容的视图。视图可以是任何聚合管道表达式的结果
例如,给定集合中的一个简单文档:
db.test.insert({ "a": 1, "b": 2, "c": 3 })
您可以使用所需字段在该集合上创建视图:
db.test.createView("testView", "test", [{ "$project": { "a": 1, "b": 2 } }])
然后退出mongo shell,您可以使用以下选项访问视图:
这仅导出命名的“集合”(实际上是一个视图)。这意味着它不只是返回视图定义(本质上是聚合管道),而是返回结果,就像它是一个真实的集合一样
然后可以通过以下方式加载生成的BSON内容:
然后,BSON转储中的内容实际写入到您所连接主机的新数据库目标中,并且使用指定的集合名称
use other
db.test.find()
{ "_id" : ObjectId("5bfb3e0eadd1d8af906ad140"), "a" : 1, "b" : 2 }
还需要注意的是,聚合管道实际上可以是任何东西,因此$match
语句可以进行过滤,您可以根据需要进行转换甚至实际“聚合”
将视图或--字段与mongoexport
同样,该实用程序也可以从视图访问内容
尽管这不是“严格的BSON”,但MongoDB实际上有一个标准,它确实保留了数据类型。这实际上包含在下的文档中
因此,这不是二进制格式,与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"
}
}
use other
db.mixed.findOne()
{
"_id" : ObjectId("5bfb428790b2b4e4241a015c"),
"a" : NumberLong(1),
"b" : NumberDecimal("123.45"),
"c" : ISODate("2018-11-26T00:47:03.033Z")
}
或在原始收藏中使用相同的内容,仅用于选择:
mongoexport --db test --collection mixed --fields a,b,c > out.json
输出完全相同。唯一的限制是,只能支持给定给find()
或类似对象的正则查询表达式。这不如a灵活,但可以对大多数需求进行基本过滤
格式由识别,许多语言也有解析器的实现,可以识别这种格式,在读取内容时,会将内容插入目标集合,并保留“类型”信息:
mongoimport --db other --collection mixed out.json
然后查看数据:
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"
}
}
use other
db.mixed.findOne()
{
"_id" : ObjectId("5bfb428790b2b4e4241a015c"),
"a" : NumberLong(1),
"b" : NumberDecimal("123.45"),
"c" : ISODate("2018-11-26T00:47:03.033Z")
}
因此,在发送二进制内容可能不可行或甚至不可取的情况下,为了数据交换的目的而存在这种格式是可能的,但维护“类型”信息是可取的
总的来说,您可以使用许多选项,而无需恢复到读取和写入二进制BSON格式,或任何其他复杂的二进制格式来存储传输之间的数据
作为“模糊”一段的注释,文档页面中列出了实际支持的BSON类型。您甚至可以将此与进行比较,以发现尽管有“谨慎”的声明,但实际上您将使用的常见类型的数据都得到了支持。虽然该规范的一些外部解释可能无法理解所有这些,但捆绑的实用程序,如mongoexport
和mongoimport
确实符合要求。感谢您的详细解释。所以,如果我错了,请纠正我的错误,但我的第一个问题的答案是,不,我不会因为使用JSON而丢失任何信息,因为正如您所说的“这不是二进制格式,而JSON确实占用了相当多的存储空间,但必要的信息确实存在”。这意味着JSON转储文件包含完全相同的信息,但它通过占用更多空间对其进行编码。所以我可以期望JSON转储文件比其BSON等效转储文件大,对吗?至于我的第二个问题:是否可以编写自己的Nodejs应用程序来进行过滤并在BSON中输出转储文件?现在我将使用您的解决方案(即创建一个视图,然后使用mongodump转储它),但我仍然有兴趣知道是否可以使用定制的Nodejs应用程序来代替。这样做的原因是性能在我的场景中非常重要,我感觉创建一个视图并随后使用mongodump将其转储将比执行一个Nodejs应用程序(该应用程序过滤数据并自动将其写入(BSON)转储文件)所需的时间要长得多。