在关系型数据库中,具有数据库和数据表的概念,数据以库和表的结构进行组织。在MongoDB中也是类似的,数据按照数据库和集合进行划分。
选择数据库:
> use tutorial
switched to db tutorial
查看当前数据库:
> db
tutorial
查看所有数据库:
> show dbs
local 0.000GB
tutorial 0.045GB
查看当前所选数据库的所有集合:
> show collections
users
MongoDB不需要先创建再选择数据库,我们直接选择一个名字,如果向其中插入数据,该数据库会被自动创建。
插入数据:
> db.users.insert({username: "smith"})
WriteResult({ "nInserted" : 1 })
和不需要建库一样,我们也不用显式的创建集合,上面例子中我们直接插入数据,users
集合就会自动生成,并向其中插入一个{username: "smith"}
这样的类似JSON的文档。
有关数据库操作命令,如果忘了,我们可以查看帮助:
> help
db.help() help on db methods
db.mycoll.help() help on collection methods
sh.help() sharding helpers
rs.help() replica set helpers
help admin administrative help
help connect connecting to a db help
help keys key shortcuts
help misc misc things to know
help mr mapreduce
show dbs show database names
show collections show collections in current database
show users show users in current database
show profile show most recent system.profile entries with time >= 1ms
show logs show the accessible logger names
show log [name] prints out the last segment of log in memory, 'global' is default
use <db_name> set current database
db.foo.find() list objects in collection foo
db.foo.find( { a : 1 } ) list objects in foo where a == 1
it result of the last line evaluated; use to further iterate
DBQuery.shellBatchSize = x set default number of items to display on shell
exit quit the mongo shell
如果想要查看一个函数的操作,可以直接键入该函数名,例如:键入db.users.find
,我们可以看到该函数接收的参数,以及源码执行逻辑:
function ( query , fields , limit , skip, batchSize, options ){
var cursor = new DBQuery( this._mongo , this._db , this ,
this._fullName , this._massageObject( query ) , fields , limit , skip , batchSize , options || this.getQueryOptions() );
var connObj = this.getMongo();
var readPrefMode = connObj.getReadPrefMode();
if (readPrefMode != null) {
cursor.readPref(readPrefMode, connObj.getReadPrefTagSet());
}
return cursor;
}
前面我们已经尝试过插入数据了:
> db.users.insert({username: "smith"})
WriteResult({ "nInserted" : 1 })
该操作会向users
这个集合中,插入一个类似JSON格式的文档。
我们可以查看刚刚插入的数据:
> db.users.find()
{ "_id" : ObjectId("5c33f6ddfb5aea6a680cccf9"), "username" : "smith" }
这里我们调用了find()
,这个函数默认会返回该集合前20个数据项。这里我们发现,我们插入的数据中除了我们设定的username
字段,还有一个随机的_id
,它就是这个文档数据的唯一主键。插入数据的时候,我们也可以设定自己的主键,如果没有_id
这个字段,MongoDB就会自动为我们生成。
注:在shell中,如果文档类型比较复杂,我们可以用.find().pretty()
的形式,输出格式化的文档,方便观看。
查看插入的文档数据个数:
> db.users.count()
2
注:这里我们为了测试,又插入了一条数据。
传递查询参数:
> db.users.find({username:"smith"})
{ "_id" : ObjectId("5c33f6ddfb5aea6a680cccf9"), "username" : "smith" }
上面我们传入了{username:"smith"}
这个查询参数,一次find()
匹配了该条数据并返回。
find()
中的条件也可以是多个,下面查询语句隐式创建了一个AND查询:
> db.users.find({ "_id" : ObjectId("5c33f6ddfb5aea6a680cccf9"), "username" : "smith" })
{ "_id" : ObjectId("5c33f6ddfb5aea6a680cccf9"), "username" : "smith" }
我们也可以使用AND操作符,把这个逻辑显示写出来,这个在终端中写起来就比较困难了,我们最好使用一个支持JSON的文本编辑器进行编写:
db.users.find({
$and: [
{"_id" : ObjectId("5c33f6ddfb5aea6a680cccf9")},
{"username" : "smith"}
]
})
返回结果和上面相同。同理,我们也可以使用$or
操作符组织OR查询。除此之外,MongoDB还支持$gt
,$lt
,$gte
,lte
,$ne
这样的比较操作符,这里就不多做介绍了。
基本的查询就先介绍这些,后续章节会更加详细介绍MongoDB的查询功能。
更新文档的一个字段需要使用update()
函数和$set
操作符。
db.users.update(
{username: "smith"},
{
$set: {country: "Canada"}
}
)
上面操作中,我们给{ "_id" : ObjectId("5c33f6ddfb5aea6a680cccf9"), "username" : "smith" }
这个文档添加了一个字段{country: "Canada"}
,我们可以自己查询一下看看结果。
注:如果update()
中不使用$set
操作符,执行的是替换更新,该文档会被直接更换成{country: "Canada"}
,一般我们不会这样操作。
除了$set
,我们还可以使用$unset
删除一个字段。
db.users.update(
{username: "smith"},
{
$unset: {country: 0}
}
)
该操作会删除country
这个字段。
更新更加复杂类型的数据:
db.users.update(
{username: "smith"},
{
$set: {
favorites: {
cities: ["cityA", "cityB"],
movies: ["movieA", "movieB", "movieC"]
}
}
}
)
MongoDB的文档可以组织的比较复杂,上面演示了创建几个数组字段。
那么如何向数组插入数据呢?我们可以使用$push
和$addToSet
操作符,第一个向数组中添加元素,第二个把数组看作集合,只会想其中添加之前不存在的元素。
db.users.update(
{username: "smith"},
{
$push: {
"favorites.movies": "movieD"
}
}
)
注:favorites.movies
使用了点语法,必须用引号括起来,否则会报错。默认则是和JavaScript相同,可以省略引号的。
下面是update()
函数的API文档,其中还有两个比较重要的参数:
upsert
:当一个文档不存在时是否插入,默认为false
multi
:是否插入多条符合匹配条件的数据,默认为false
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ]
}
)
删除一个数据文档:
> db.users.remove({ "_id" : ObjectId("5c33f721fb5aea6a680cccfa")})
WriteResult({ "nRemoved" : 1 })
删除一个集合:
> db.users.drop()
true
删除集合就像RDBMS中删除一个数据表一样。