今天给大家介绍一款分析MongoDB数据库表结构的软件 -- Varity.对于MongoDB这种Schema Free的数据库来说,用软件自带的查询collection中存储的数据情况很难一眼就看出具体的数据结构,Tomá Dvoák 作者写了一个Variety.js的脚本就很容易理解没个collection中的数据结构。作者将工具托管在github上,并且欢迎任何人来提供建议或者添加功能。以下Variety的特点翻译自作者的博客:
collection信息输出格式是ASCII的。
可以很清晰看到每个key使用的是什么类型的数据格式
可以看到没个key在这个collection的使用率是多少
可以限制documents的查询数量
可以限制查询documents的深度
可以只分析documents的子集
可以对查询结果排序
可以保存查询结果
可以以JSON格式输出
工具简介易用,没用任何其他库依赖
Variety的下载地址 https://github.com/variety/variety。
使用方法:
mongo DATABASE_NAME --eval "var collection = 'COLL_NAME' " variety.js,比如我的DATABASE_NAME 是test, COLL_NAME是users,
我事先插入的数据是
db.users.insert({name: "Tom", bio: "A nice guy.", pets: ["monkey", "fish"], someWeirdLegacyKey: "I like Ike!"});
db.users.insert({name: "Dick", bio: "I swordfight.", birthday: new Date("1974/03/14")});
db.users.insert({name: "Harry", pets: "egret", birthday: new Date("1984/03/14")});
db.users.insert({name: "Shanker", bio: "a va?"});
正常的查询Users的回显是这样的
> db.users.find()
{ "_id" : ObjectId("56cfc28fbdae9b9a922a19cb"), "name" : "Tom", "bio" : "A nice guy", "pets" : [ "monkey", "fish" ], "someWeirdLegacyKey" : "I like ike!" }
{ "_id" : ObjectId("56cfc2acbdae9b9a922a19cc"), "name" : "Dick", "bio" : "I swordfight." }
{ "_id" : ObjectId("56cfc2c6bdae9b9a922a19cd"), "name" : "Harry", "pets" : "egret" }
{ "_id" : ObjectId("56cfc2e0bdae9b9a922a19ce"), "name" : "Shanker", "bio" : "caca" }
用Variety查询结果是这样的
mongo test --eval "var collection = 'users'" variety.js
MongoDB shell version: 2.4.9
connecting to: test
Variety: A MongoDB Schema Analyzer
Version 1.5.0, released 14 May 2015
Using collection of "users"
Using query of { }
Using limit of 4
Using maxDepth of 99
Using sort of { "_id" : -1 }
Using outputFormat of "ascii"
Using persistResults of false
Using resultsDatabase of "varietyResults"
Using resultsCollection of "usersKeys"
Using resultsUser of null
Using resultsPass of null
Using plugins of [ ]
+--------------------------------------------------------------------+
| key | types | occurrences | percents |
| ------------------ | -------------------- | ----------- | -------- |
| _id | ObjectId | 4 | 100.0 |
| name | String | 4 | 100.0 |
| bio | String | 3 | 75.0 |
| pets | String (1),Array (1) | 2 | 50.0 |
| someWeirdLegacyKey | String | 1 | 25.0 |
+--------------------------------------------------------------------+
是不是格式很友好,很容易读懂了呢?
如果数据库用的不是默认端口,可以用--port参数:
mongo DATABASE_NAME --port 27111 --eval " var collection = 'COLL_NAME' " variety.js
如果db文件不在默认文件,可以用--dbpath参数:
mongo DATABASE_NAME --dbpath /path/to/database/folder --eval "var collection = 'COLL_NAME' " variety.js
如果需要对查询进行排序的话可以这样用:
mongo DATABASE_NAME --eval "var collection = 'COLL_NAME', sort = { date : -1 }" variety.js
如果需要JSON的输出格式的话可以这样用:
mongo DATABASE_NAME --eval "var collection = 'users', outputFormat = 'json' " variety.js
如果一个collection有10亿个数据,我们可以限制查询的数量,用limit来限定:
mongo DATABASE_NAME --eval "var collection ='users', limit = 1000 " variety.js
如果某个colletions嵌套的层数太多了,可以用maxDepth来限制查询:
db.users.insert({name:"Walter", someNestedObject:{a:{b:{c:{d:{e:1}}}}}});
[ibmcloud@bravo:~/variety04:05]$mongo test --eval "var collection = 'users' " variety.js
MongoDB shell version: 2.4.9
connecting to: test
Variety: A MongoDB Schema Analyzer
Version 1.5.0, released 14 May 2015
Using collection of "users"
Using query of { }
Using limit of 5
Using maxDepth of 99
Using sort of { "_id" : -1 }
Using outputFormat of "ascii"
Using persistResults of false
Using resultsDatabase of "varietyResults"
Using resultsCollection of "usersKeys"
Using resultsUser of null
Using resultsPass of null
Using plugins of [ ]
+----------------------------------------------------------------------------+
| key | types | occurrences | percents |
| -------------------------- | -------------------- | ----------- | -------- |
| _id | ObjectId | 5 | 100.0 |
| name | String | 5 | 100.0 |
| bio | String | 3 | 60.0 |
| pets | String (1),Array (1) | 2 | 40.0 |
| someNestedObject | Object | 1 | 20.0 |
| someNestedObject.a | Object | 1 | 20.0 |
| someNestedObject.a.b | Object | 1 | 20.0 |
| someNestedObject.a.b.c | Object | 1 | 20.0 |
| someNestedObject.a.b.c.d | Object | 1 | 20.0 |
| someNestedObject.a.b.c.d.e | Number | 1 | 20.0 |
| someWeirdLegacyKey | String | 1 | 20.0 |
+----------------------------------------------------------------------------+
[ibmcloud@bravo:~/variety05:06]$mongo test --eval "var collection = 'users', maxDepth = 3" variety.js
MongoDB shell version: 2.4.9
connecting to: test
Variety: A MongoDB Schema Analyzer
Version 1.5.0, released 14 May 2015
Using collection of "users"
Using query of { }
Using limit of 5
Using maxDepth of 3
Using sort of { "_id" : -1 }
Using outputFormat of "ascii"
Using persistResults of false
Using resultsDatabase of "varietyResults"
Using resultsCollection of "usersKeys"
Using resultsUser of null
Using resultsPass of null
Using plugins of [ ]
+----------------------------------------------------------------------+
| key | types | occurrences | percents |
| -------------------- | -------------------- | ----------- | -------- |
| _id | ObjectId | 5 | 100.0 |
| name | String | 5 | 100.0 |
| bio | String | 3 | 60.0 |
| pets | String (1),Array (1) | 2 | 40.0 |
| someNestedObject | Object | 1 | 20.0 |
| someNestedObject.a | Object | 1 | 20.0 |
| someNestedObject.a.b | Object | 1 | 20.0 |
| someWeirdLegacyKey | String | 1 | 20.0 |
+----------------------------------------------------------------------+
如果需要制定条件的查询,比如carddAbout为true的,可以这样:
mongo DATABASE_NAME --eval "var collection = 'COLL_NAME', query = {'caredAbout':true}" variety.js
需要注意的是,Variety在对数据结构进行分析的时候,实际是用MapReduce来做的,会进行全表扫描操作,所以如果是对线上库进行分析,那么建议最好使用一个不提供服务的备份库或者在业务低峰来做。避免给线上业务造成压力。
参考地址:
http://www.acetolyne.net/Projects7/node/48
https://github.com/variety/variety
http://www.mongoing.com/archives/2282