Abel'Blog

我干了什么?究竟拿了时间换了什么?

0%

MongoDB基本用法

简介

MongoDB是面向文档的数据库。和关系型数据库不同的是它能非常方便的扩展字段。而且对于文件类型的内容有非常好的可塑性。如制作游戏的时候,我们对于一个role的数据结构的定义,可能不是从一开始就能固化好。策划可能对运营上线的游戏玩法的修改、增删可能会引起对于存储的字段有影响。如果使用的技术是传统的MySQL中的表中的字段来存储role的数据,将会需要开发者编写数据库变更的SQL语句,并且通知运维人员同步到全部服务器。这个过程可能需要还需要去编写检查脚本以防止在生产环境中可能未能将更新在全部服务器中执行完,而造成部分服务器的数据回档。如果使用MongoDB中的文档数据结构,就会比较方便了。MongoDB中的文档基本上是一个类似json语法的描述,存储到文件中的时候是使用的bson格式。

增删改查

mongo shell简单的用法

在mongo命令行也类似于mysql的命令行。他是使用js编写的。所以在这个命令行中能直接解析执行javascript的语法。

1
2
3
4
5
6
7
8
9
10
11
$ mongo
MongoDB shell version: 2.6.11
connecting to: test
> show dbs -- 查看本地全部数据库
admin (empty)
local 0.078GB
> db -- 查看在使用的数据库
test
> use local -- 切换数据库
switched to db local
> show collections -- 查看这个db里面的全部表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
mongodb://[username:password@]host1[:port1][,host2[:port2],…[,hostN[:portN]]][/[database][?options]]

mongodb://[username:password@]127.0.0.1:27017/?authSource=admin&readPreference=primary&appname=MongoDB%20Compass&ssl=false

注:并非所有MongoDB驱动都支持完整的连接字符串,不支持此格式连接字串的驱动会有替代连接方案,具体请参照驱动自身的说明文档。

 mongodb:// 是连接字串必须的前缀字串
 username:password@ 可选项,连接到数据库后会尝试验证登陆
 host1 必须的指定至少一个host
 :portX 可选项,默认连接到27017
 /database 如果指定username:password@,连接并验证登陆指定数据库。若不指定,默认打开admin数据库。
 ?options 是连接选项。如果不使用/database,则前面需要加上/。所有连接选项都是键值对name=value,键值对之间通过&或;(分号)隔开
实例:
mongodb://[username:password@]127.0.0.1:27017/?authSource=admin&readPreference=primary&appname=MongoDB%20Compass&ssl=false

在test里面我们添加一条blog信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
> use local
switched to db local
> use test
switched to db test
> post = {"title":"LOL",
... "content":"league of legends is one of my favorite games.",
... "date":new Date()}
{
"title" : "LOL",
"content" : "league of legends is one of my favorite games.",
"date" : ISODate("2016-05-20T23:28:38.391Z")
}
> db.blog.insert(post)
WriteResult({ "nInserted" : 1 })

1
2
3
4
5
6
7
> db.blog.findOne()
{
"_id" : ObjectId("573f9e01e00e5fff255950f2"),
"title" : "LOL",
"content" : "league of legends is one of my favorite games.",
"date" : ISODate("2016-05-20T23:28:38.391Z")
}

1
2
3
4
5
6
7
8
9
10
11
12
> post.comments = []
[ ]
> db.blog.update({title:"LOL"},post)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.blog.findOne()
{
"_id" : ObjectId("573f9e01e00e5fff255950f2"),
"title" : "LOL",
"content" : "league of legends is one of my favorite games.",
"date" : ISODate("2016-05-20T23:28:38.391Z"),
"comments" : [ ]
}

1
2
3
4
> db.blog.remove({title:"LOL"},post)
WriteResult({ "nRemoved" : 1 })
> db.blog.findOne()
null

数据结构介绍

类型 说明
null null用于表示空值或者不存在的字段。 {“x”:null}
布尔 布尔类型有两个值’true’和’false1’. {“X”:true}
数值 64位浮点数。或者是{“x”:NumberInt(“3”)}{“x”:NumberLong(“3”)}
字符串 UTF-8字符串都可表示为字符串类型的数据: {“x” : “foobar”}
日期 日期类型存储的是从标准纪元开始的毫秒数。不存储时区: {“X” : new Date()}
正则表达式 文档中可以包含正则表达式,采用JavaScript的正则表达式语法: {“x” : /foobar/i}
代码 文档中还可以包含JavaScript代码:{“x” : function() { /……/ }}

导出/导入MongoDB

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
mongodump --help
Export MongoDB data to BSON files.

Options:
--help produce help message
-v [ --verbose ] be more verbose (include multiple times
for more verbosity e.g. -vvvvv)
--quiet silence all non error diagnostic
messages
--version print the program's version and exit
-h [ --host ] arg mongo host to connect to ( <set
name>/s1,s2 for sets)
--port arg server port. Can also use --host
hostname:port
--ipv6 enable IPv6 support (disabled by
default)
--ssl use SSL for all connections
--sslCAFile arg Certificate Authority file for SSL
--sslPEMKeyFile arg PEM certificate/key file for SSL
--sslPEMKeyPassword arg password for key in PEM file for SSL
--sslCRLFile arg Certificate Revocation List file for
SSL
--sslAllowInvalidHostnames allow connections to servers with
non-matching hostnames
--sslAllowInvalidCertificates allow connections to servers with
invalid certificates
--sslFIPSMode activate FIPS 140-2 mode at startup
-u [ --username ] arg username
-p [ --password ] arg password
--authenticationDatabase arg user source (defaults to dbname)
--authenticationMechanism arg (=MONGODB-CR)
authentication mechanism
--gssapiServiceName arg (=mongodb) Service name to use when authenticating
using GSSAPI/Kerberos
--gssapiHostName arg Remote host name to use for purpose of
GSSAPI/Kerberos authentication
--dbpath arg directly access mongod database files
in the given path, instead of
connecting to a mongod server - needs
to lock the data directory, so cannot
be used if a mongod is currently
accessing the same path
--directoryperdb each db is in a separate directory
(relevant only if dbpath specified)
--journal enable journaling (relevant only if
dbpath specified)
-d [ --db ] arg database to use
-c [ --collection ] arg collection to use (some commands)
-o [ --out ] arg (=dump) output directory or "-" for stdout
-q [ --query ] arg json query
--oplog Use oplog for point-in-time
snapshotting
--repair try to recover a crashed database
--forceTableScan force a table scan (do not use
$snapshot)
--dumpDbUsersAndRoles Dump user and role definitions for the
given database

mongodump -d test -o ./test.bson

$ mongodump -d test -o ./test
connected to: 127.0.0.1
2016-05-21T09:31:34.643+0800 DATABASE: test to ./test/test
2016-05-21T09:31:34.644+0800 test.system.indexes to ./test/test/system.indexes.bson
2016-05-21T09:31:34.644+0800 1 documents
2016-05-21T09:31:34.644+0800 test.blog to ./test/test/blog.bson
2016-05-21T09:31:34.645+0800 1 documents
2016-05-21T09:31:34.645+0800 Metadata for test.blog to ./test/test/blog.metadata.json

$ tree ./test
./test
└── test
├── blog.bson
├── blog.metadata.json
└── system.indexes.bson


1 directory, 3 files

$ mongorestore --help
Import BSON files into MongoDB.

usage: mongorestore [options] [directory or filename to restore from]
Options:
--help produce help message
-v [ --verbose ] be more verbose (include multiple times
for more verbosity e.g. -vvvvv)
--quiet silence all non error diagnostic
messages
--version print the program's version and exit
-h [ --host ] arg mongo host to connect to ( <set
name>/s1,s2 for sets)
--port arg server port. Can also use --host
hostname:port
--ipv6 enable IPv6 support (disabled by
default)
--ssl use SSL for all connections
--sslCAFile arg Certificate Authority file for SSL
--sslPEMKeyFile arg PEM certificate/key file for SSL
--sslPEMKeyPassword arg password for key in PEM file for SSL
--sslCRLFile arg Certificate Revocation List file for
SSL
--sslAllowInvalidHostnames allow connections to servers with
non-matching hostnames
--sslAllowInvalidCertificates allow connections to servers with
invalid certificates
--sslFIPSMode activate FIPS 140-2 mode at startup
-u [ --username ] arg username
-p [ --password ] arg password
--authenticationDatabase arg user source (defaults to dbname)
--authenticationMechanism arg (=MONGODB-CR)
authentication mechanism
--gssapiServiceName arg (=mongodb) Service name to use when authenticating
using GSSAPI/Kerberos
--gssapiHostName arg Remote host name to use for purpose of
GSSAPI/Kerberos authentication
--dbpath arg directly access mongod database files
in the given path, instead of
connecting to a mongod server - needs
to lock the data directory, so cannot
be used if a mongod is currently
accessing the same path
--directoryperdb each db is in a separate directory
(relevant only if dbpath specified)
--journal enable journaling (relevant only if
dbpath specified)
-d [ --db ] arg database to use
-c [ --collection ] arg collection to use (some commands)
--objcheck validate object before inserting
(default)
--noobjcheck don't validate object before inserting
--filter arg filter to apply before inserting
--drop drop each collection before import
--oplogReplay replay oplog for point-in-time restore
--oplogLimit arg include oplog entries before the
provided Timestamp (seconds[:ordinal])
during the oplog replay; the ordinal
value is optional
--keepIndexVersion don't upgrade indexes to newest version
--noOptionsRestore don't restore collection options
--noIndexRestore don't restore indexes
--restoreDbUsersAndRoles Restore user and role definitions for
the given database
--w arg (=0) minimum number of replicas per write


$ mongorestore -db test_duplicate ./test/test/
connected to: 127.0.0.1
2016-05-21T09:33:02.967+0800 ./test/test/blog.bson
2016-05-21T09:33:02.967+0800 going into namespace [test_duplicate.blog]
Restoring to test_duplicate.blog without dropping. Restored data will be inserted without raising errors; check your server log
1 objects found
2016-05-21T09:33:02.967+0800 Creating index: { key: { _id: 1 }, name: "_id_", ns: "test_duplicate.blog" }

$ mongo
MongoDB shell version: 2.6.11
connecting to: test
> use test_duplicate
switched to db test_duplicate
> db.blog.find()
{ "_id" : ObjectId("573fba64a1fc07b6731428f8"), "title" : "LOL", "content" : "league of legends is one of my favorite games.", "date" : ISODate("2016-05-21T01:30:55.673Z") }

MongoDB的引用

MongoDB 数据库引用

在MongoDB中存在1:n的数据结构。简单的方式,就是直接使用MongoDB的数据结构直接存储。

mongo库

[1] mongo-go-官方库
[2] mgo库

使用mgo做简单操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import (
"github.com/globalsign/mgo"
"github.com/globalsign/mgo/bson"
)
type Entry struct {
ID bson.ObjectId `bson:"_id"`
Name String `bson:"name"`
}
// 连接mongodb
dbInfo := &mgo.DialInfo{}
dbInfo.Addrs = []string{"127.0.0.1:27017"}
dbInfo.Database = "TestDB"
mongoSess, err := mgo.DialWithInfo(dbInfo)
if err != nil {
return err
}
// 获得数据库
mongoDB = mongoSess.DB(dbInfo.Database)
if mongoDB == nil {
return errors.New("DB not exists.")
}
// 获得collection
ecol = MongoDB.C("tbl_entry")
// 创建索引
index := mgo.Index{
Key: []string{"uid"},
Unique: false, // 其中有很多的类型
}
if err := icol.EnsureIndex(index); err != nil {
fmt.Print(err.Error())
}
// 插入、替换类似MySQL中的repace语句。
e := &Entry{
ID: bson.NewObjectId(),
Name: "Sean",
}
ecol.UpsertId(e.ID,e)
// 查询
id := bson.ObjectIdHex("618b838f17aa967914fbc601") // 在mongodb中,id其实就是12byte(24位16进值数字)的数字。数据里面存在一个时间戳32bit+64bit的数字,里面还存储了机器码,顺序数字。
if err := ucol.FindId(id).One(e); err == nil {
//
}
// 修改
ecol.RemoveId(id)

参考资料