3.1 MongoDB CRUD介绍

从网址

https://raw.githubusercontent.com/mongodb/docs-assets/primer-dataset/dataset.json 下载示例文件

使用如下命令导入MongoDB,数据库test 集合名restaurants 。

[root@localhost ~]# mongoimport --db test --collection restaurants --drop --file dataset.txt 
2016-01-04T20:16:05.541+0800connected to: localhost
2016-01-04T20:16:05.543+0800dropping: test.restaurants
2016-01-04T20:16:08.362+0800imported 25359 documents

使用mongo客户端程序连接MongoDB

[root@localhost ~]# mongo
MongoDB shell version: 3.2.0
connecting to: test

默认连接到test数据库,可以使用use命令切换数据库(指定的数据库没有时,则创建)

> use test_db
switched to db test_db


mongodb启动时默认监听的IP地址为127.0.0.1 如果需要网络访问mongodb,则修改配置文件/etc/mongod.conf 

# network interfaces
net:
  port: 27017
  bindIp: 192.168.199.219


前面讲过MongoDB使用文档结构来存储数据,文档是一张类JSON的格式。严格来说,MongoDB使用BSON来存储数据,BSON是JSON的二进制表现形式。

所有的文档存在一个称之为Collections中,一个collection由一组相关的文档组成。你可以把collection看成关系数据库的表。

MongoDB-Manual-Master 读书笔记-CRUD操作_MongoDB

3.1.1 数据库操作

Query

MongoDB中使用db.collection.find()检索数据,collection表示具体的集合的名称。

此方法接受两个参数:查询条件、查询结果列(数据映射),并且返回一个cursor 。

MongoDB-Manual-Master 读书笔记-CRUD操作_读书笔记_02

上图表示在users集合中查询条件满足age>=18的,并且返回name,address列,返回结果只取5行数据。

projection部分,如果指定{name:0}则表示除去name的所有列。


其对应的SQL写法为:

MongoDB-Manual-Master 读书笔记-CRUD操作_读书笔记_03


db.collection.findOne()则只返回第一条数据

示例:

> db.restaurants.findOne()
{
	"_id" : ObjectId("568a628607ce6e1e3c2e0a25"),
	"address" : {
		"building" : "1007",
		"coord" : [
			-73.856077,
			40.848447
		],
		"street" : "Morris Park Ave",
		"zipcode" : "10462"
	},
	"borough" : "Bronx",
	"cuisine" : "Bakery",
	"grades" : [
		{
			"date" : ISODate("2014-03-03T00:00:00Z"),
			"grade" : "A",
			"score" : 2
		},
		{
			"date" : ISODate("2013-09-11T00:00:00Z"),
			"grade" : "A",
			"score" : 6
		},
		{
			"date" : ISODate("2013-01-24T00:00:00Z"),
			"grade" : "A",
			"score" : 10
		},
		{
			"date" : ISODate("2011-11-23T00:00:00Z"),
			"grade" : "A",
			"score" : 9
		},
		{
			"date" : ISODate("2011-03-10T00:00:00Z"),
			"grade" : "B",
			"score" : 14
		}
	],
	"name" : "Morris Park Bake Shop",
	"restaurant_id" : "30075445"
}

查询address.building = 1008的

> db.restaurants.findOne({"address.building":"1008"})
{
	"_id" : ObjectId("568a628607ce6e1e3c2e0b1b"),
	"address" : {
		"building" : "1008",
		"coord" : [
			-73.9668354,
			40.7568328
		],
		"street" : "2 Avenue",
		"zipcode" : "10022"
	},
	"borough" : "Manhattan",
	"cuisine" : "French",
	"grades" : [
		{
			"date" : ISODate("2014-02-04T00:00:00Z"),
			"grade" : "A",
			"score" : 11
		},
		{
			"date" : ISODate("2013-04-10T00:00:00Z"),
			"grade" : "A",
			"score" : 7
		},
		{
			"date" : ISODate("2012-02-27T00:00:00Z"),
			"grade" : "A",
			"score" : 10
		},
		{
			"date" : ISODate("2011-11-02T00:00:00Z"),
			"grade" : "A",
			"score" : 4
		},
		{
			"date" : ISODate("2011-07-11T00:00:00Z"),
			"grade" : "A",
			"score" : 9
		},
		{
			"date" : ISODate("2011-03-07T00:00:00Z"),
			"grade" : "C",
			"score" : 39
		}
	],
	"name" : "La Mangeoire",
	"restaurant_id" : "40368971"
}

只选择grades字段

> db.restaurants.findOne({"address.building":"1008"},{"grades":1})
{
	"_id" : ObjectId("568a628607ce6e1e3c2e0b1b"),
	"grades" : [
		{
			"date" : ISODate("2014-02-04T00:00:00Z"),
			"grade" : "A",
			"score" : 11
		},
		{
			"date" : ISODate("2013-04-10T00:00:00Z"),
			"grade" : "A",
			"score" : 7
		},
		{
			"date" : ISODate("2012-02-27T00:00:00Z"),
			"grade" : "A",
			"score" : 10
		},
		{
			"date" : ISODate("2011-11-02T00:00:00Z"),
			"grade" : "A",
			"score" : 4
		},
		{
			"date" : ISODate("2011-07-11T00:00:00Z"),
			"grade" : "A",
			"score" : 9
		},
		{
			"date" : ISODate("2011-03-07T00:00:00Z"),
			"grade" : "C",
			"score" : 39
		}
	]
}

显示除了grades的其他字段

> db.restaurants.findOne({"address.building":"1008"},{"grades":0})
{
	"_id" : ObjectId("568a628607ce6e1e3c2e0b1b"),
	"address" : {
		"building" : "1008",
		"coord" : [
			-73.9668354,
			40.7568328
		],
		"street" : "2 Avenue",
		"zipcode" : "10022"
	},
	"borough" : "Manhattan",
	"cuisine" : "French",
	"name" : "La Mangeoire",
	"restaurant_id" : "40368971"

查询zipcode=10022 并且cuisine="French"的

> db.restaurants.findOne({"address.zipcode":"10022","cuisine":"French"})
{
	"_id" : ObjectId("568a628607ce6e1e3c2e0a85"),
	"address" : {
		"building" : "3",
		"coord" : [
			-73.97557069999999,
			40.7596796
		],
		"street" : "East   52 Street",
		"zipcode" : "10022"
	},
	"borough" : "Manhattan",
	"cuisine" : "French",
	"grades" : [
		{
			"date" : ISODate("2014-04-09T00:00:00Z"),
			"grade" : "A",
			"score" : 10
		},
		{
			"date" : ISODate("2013-03-05T00:00:00Z"),
			"grade" : "A",
			"score" : 9
		},
		{
			"date" : ISODate("2012-02-02T00:00:00Z"),
			"grade" : "A",
			"score" : 13
		}
	],
	"name" : "La Grenouille",
	"restaurant_id" : "40365264"
}

查询zipcode=10022 或者 cuisine="French"的

> db.restaurants.findOne({"$or":[{"address.zipcode":"10022"},{"cuisine":"French"}]})
{
	"_id" : ObjectId("568a628607ce6e1e3c2e0a51"),
	"address" : {
		"building" : "437",
		"coord" : [
			-73.975393,
			40.757365
		],
		"street" : "Madison Avenue",
		"zipcode" : "10022"
	},
	"borough" : "Manhattan",
	"cuisine" : "American ",
	"grades" : [
		{
			"date" : ISODate("2014-06-03T00:00:00Z"),
			"grade" : "A",
			"score" : 9
		},
		{
			"date" : ISODate("2013-06-07T00:00:00Z"),
			"grade" : "A",
			"score" : 5
		},
		{
			"date" : ISODate("2012-06-29T00:00:00Z"),
			"grade" : "A",
			"score" : 12
		},
		{
			"date" : ISODate("2012-02-06T00:00:00Z"),
			"grade" : "A",
			"score" : 11
		},
		{
			"date" : ISODate("2011-06-23T00:00:00Z"),
			"grade" : "A",
			"score" : 13
		}
	],
	"name" : "Berkely",
	"restaurant_id" : "40363685"
}

查询grades.score大于13的

> db.restaurants.findOne({"grades.score":{"$gt":13}})
{
	"_id" : ObjectId("568a628607ce6e1e3c2e0a25"),
	"address" : {
		"building" : "1007",
		"coord" : [
			-73.856077,
			40.848447
		],
		"street" : "Morris Park Ave",
		"zipcode" : "10462"
	},
	"borough" : "Bronx",
	"cuisine" : "Bakery",
	"grades" : [
		{
			"date" : ISODate("2014-03-03T00:00:00Z"),
			"grade" : "A",
			"score" : 2
		},
		{
			"date" : ISODate("2013-09-11T00:00:00Z"),
			"grade" : "A",
			"score" : 6
		},
		{
			"date" : ISODate("2013-01-24T00:00:00Z"),
			"grade" : "A",
			"score" : 10
		},
		{
			"date" : ISODate("2011-11-23T00:00:00Z"),
			"grade" : "A",
			"score" : 9
		},
		{
			"date" : ISODate("2011-03-10T00:00:00Z"),
			"grade" : "B",
			"score" : 14
		}
	],
	"name" : "Morris Park Bake Shop",
	"restaurant_id" : "30075445"
}

Insert

MongoDB中使用如下方法插入数据

db.collection.insertOne()

db.collection.insertMany()

db.collection.insert()


db.collection.insertOne() 3.2 新增方法

MongoDB-Manual-Master 读书笔记-CRUD操作_CRUD_04上图表示往users集合中插入一个文档

与如下图中的SQL语句等效

MongoDB-Manual-Master 读书笔记-CRUD操作_读书笔记_05

> db.users.insertOne({
... name:"dinglq",
... age:26
... ,status:"A",
... groups:["news","sports"]
... })
{
"acknowledged" : true,
"insertedId" : ObjectId("568a84a5a3e3eabd25b468af")
}


db.collection.insertMany() 是3.2版本新增功能,一次插入多个文档

MongoDB-Manual-Master 读书笔记-CRUD操作_读书笔记_06

> db.users.insertMany([
{name:"dinglq", age:26 ,status:"A", groups:["news","sports"]}, 
{name:"zhangdd",age:30,status:"B"}, 
{name:"vincent",age:44}])

{
	"acknowledged" : true,
	"insertedIds" : [
		ObjectId("568a85ada3e3eabd25b468b0"),
		ObjectId("568a85ada3e3eabd25b468b1"),
		ObjectId("568a85ada3e3eabd25b468b2")
	]
}


db.collection.insert() 向集合中添加一个文档,或者一组文档。


MongoDB-Manual-Master 读书笔记-CRUD操作_CRUD_07


update

db.collection.updateOne()

db.collection.updateMany()

db.collection.replaceOne()

db.collection.update()


db.collection.updateOne() 3.2新增方法,只更新目中数据的第一条


MongoDB-Manual-Master 读书笔记-CRUD操作_MongoDB_08

更新users集合,条件是age<=18,将status的值改为reject 。

该语句等价于如下sql

MongoDB-Manual-Master 读书笔记-CRUD操作_CRUD_09

> db.users.updateOne({name:"dinglq"},{"$set":{"age":36}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.users.find({name:"dinglq"})
{ "_id" : ObjectId("568a84a5a3e3eabd25b468af"), "name" : "dinglq", "age" : 36, "status" : "A", "groups" : [ "news", "sports" ] }
{ "_id" : ObjectId("568a85ada3e3eabd25b468b0"), "name" : "dinglq", "age" : 26, "status" : "A", "groups" : [ "news", "sports" ] }
> db.users.updateMany({name:"dinglq"},{"$inc":{"age":4}})
{ "acknowledged" : true, "matchedCount" : 2, "modifiedCount" : 2 }
> db.users.find({name:"dinglq"})
{ "_id" : ObjectId("568a84a5a3e3eabd25b468af"), "name" : "dinglq", "age" : 40, "status" : "A", "groups" : [ "news", "sports" ] }
{ "_id" : ObjectId("568a85ada3e3eabd25b468b0"), "name" : "dinglq", "age" : 30, "status" : "A", "groups" : [ "news", "sports" ] }

使用$push向数组类型的数据添加元素。

> db.users.findOne()
{
	"_id" : ObjectId("568a84a5a3e3eabd25b468af"),
	"name" : "dinglq",
	"age" : 40,
	"status" : "A",
	"groups" : [
		"news",
		"sports"
	]
}
> db.users.updateOne({"name":"dinglq"},{"$push":{"groups":"reading"} })
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.users.findOne()
{
	"_id" : ObjectId("568a84a5a3e3eabd25b468af"),
	"name" : "dinglq",
	"age" : 40,
	"status" : "A",
	"groups" : [
		"news",
		"sports",
		"reading"
	]
}

使用$push添加元素时,不会检查该值是否存在,例如

> db.users.updateOne({"name":"dinglq"},{"$push":{"groups":"reading"} })
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.users.findOne()
{
	"_id" : ObjectId("568a84a5a3e3eabd25b468af"),
	"name" : "dinglq",
	"age" : 40,
	"status" : "A",
	"groups" : [
		"news",
		"sports",
		"reading",
		"reading"
	]
}

可见,groups中有两个"reading"的值。

如何避免呢?

> db.users.updateOne({"name":"dinglq"},{"$addToSet":{"groups":"news"} })
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 0 }

使用$addToSet时,会检查该值是否存在,存在则不再插入。


使用$pop从数组的尾部或头部删除内容

> db.users.updateOne({"name":"dinglq"},{"$pop":{"groups":1}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.users.findOne({"name":"dinglq"})
{
	"_id" : ObjectId("568a84a5a3e3eabd25b468af"),
	"name" : "dinglq",
	"age" : 40,
	"status" : "A",
	"groups" : [
		"news",
		"sports",
		"reading"
	]
}

如果想从数组头部开始删除数据

> db.users.updateOne({"name":"dinglq"},{"$pop":{"groups":-1}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.users.findOne({"name":"dinglq"})
{
	"_id" : ObjectId("568a84a5a3e3eabd25b468af"),
	"name" : "dinglq",
	"age" : 40,
	"status" : "A",
	"groups" : [
		"sports",
		"reading"
	]
}

指定数组中的内容删除

> db.users.updateOne({"name":"dinglq"},{"$pull":{"groups":"sports"}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }


db.collection.updateMany() 3.2新增方法,更新命中的所有文档

MongoDB-Manual-Master 读书笔记-CRUD操作_读书笔记_10


db.collection.replaceOne() 3.2新增方法,使用新指定的文档替换命中的第一个文档

MongoDB-Manual-Master 读书笔记-CRUD操作_MongoDB_11