MongoDB的CRUD

mongod是一个文本型数据库,存入数据库的都是一个一个文本。文本用{}括起来,并且文本中的内容都是键值对,和json格式差不多,但是在mongo中,它是一种和json格式很像的bson格式
比如{“a”:1}就是一个文本,{“a”:{“b”:1,“c”:2}}是复杂的嵌入性文本
1.insert
1)db.collection.insertOne()添加一个文本

db.collection.insertOne({"f":6})
{
	"acknowledged" : true,
	"insertedId" : ObjectId("5a981304007156b408f7d902")
}

插入成功返回成功插入文本的_id
2)db.collection.insertMany()添加多个文本
按照自己的理解插入多条数据

db.collection.insertMany({"d":4},{"e":5})
2018-03-01T07:43:38.088-0700 E QUERY    [thread1] TypeError: documents.map is not a function :
DBCollection.prototype.insertMany@src/mongo/shell/crud_api.js:283:1

看了mongo shell methods的实例才发现方法参数是一个数组

db.collection.insertMany([{"d":4},{"e":5}])
{
	"acknowledged" : true,
	"insertedIds" : [
		ObjectId("5a9811c5007156b408f7d900"),
		ObjectId("5a9811c5007156b408f7d901")
	]
}

成功插入以后会返回所有插入文本的_id
3)db.collection.insert()可以添加进一个,也可以添加进多个
eg

db.test_update.insert({"a":1})
WriteResult({ "nInserted" : 1 })

db.test_update.insert(db.collection.insert([{"c":3},{"g":7}])
BulkWriteResult({
	"writeErrors" : [ ],
	"writeConcernErrors" : [ ],
	"nInserted" : 2,
	"nUpserted" : 0,
	"nMatched" : 0,
	"nModified" : 0,
	"nRemoved" : 0,
	"upserted" : [ ]
})
)

会返回成功插入文本的数量
4)db.collection.save()

db.collection.save({item:"book", qty:40})
WriteResult({ "nInserted" : 1 })
db.collection.save({"_id":100,"item":"water","qty":30})
WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : 100 })

调用save插入数据的两种情况,一是不指定_id,相当于insert()方法,指定_id,相当于update with upsert。如果指定的_id在数据库中存在,则这条数据将会被更新,否则插入这条数据
此时插入的数据:

{ "_id" : ObjectId("5a98174a007156b408f7d907"), "item" : "book", "qty" : 40 }
{ "_id" : 100, "item" : "water", "qty" : 30 }

在执行一次指定_id的save()方法

db.collection.save({"_id":100,"item":"juice"})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

此时数据库中的数据:

{ "_id" : ObjectId("5a98174a007156b408f7d907"), "item" : "book", "qty" : 40 }
{ "_id" : 100, "item" : "juice" }

使用save插入多条数据

db.collection.save([{"x":1},{"y":2},{"z":3}])
BulkWriteResult({
	"writeErrors" : [ ],
	"writeConcernErrors" : [ ],
	"nInserted" : 3,
	"nUpserted" : 0,
	"nMatched" : 0,
	"nModified" : 0,
	"nRemoved" : 0,
	"upserted" : [ ]
})

insert()和save()的区别:
如果不指定_id,则insert()和save()之间没什么区别
如果指定了_id,并且这个_id在数据库中存在,则save()将更新数据库,但是insert()不会对数据库起任何改变

db.collection.find()
{ "_id" : 100, "item" : "water", "qty" : 30 }
db.collection.insert({"_id":100, "item":"test"})
WriteResult({
	"nInserted" : 0,
	"writeError" : {
		"code" : 11000,
		"errmsg" : "E11000 duplicate key error collection: admin.collection index: _id_ dup key: { : 100.0 }"
	}
})

插入数据将会报主键重复
对于insert方法,成功以后会返回两种信息:一是成功插入文本的条数,二是成功插入文本的objectId
2.delete
1)db.collection.deleteMany({})删除所有文本

db.collection.deleteMany({})
{ "acknowledged" : true, "deletedCount" : 4 }
db.collection.count()
0

删除成功以后会返回删除的条数
2)db.collection.deleteMany(new Document(),condition)删除所有满足条件的文本

db.collection.deleteMany({"a":1})
{ "acknowledged" : true, "deletedCount" : 2 }

删除所有含a:1的文本

db.collection.deleteMany({"a":{$gt:2}})
{ "acknowledged" : true, "deletedCount" : 2 }

删除含a>2的所有文本
在复杂一些,包含多个条件
数据库中的数据:

{ "_id" : ObjectId("5a98b9641435c363f9c0686f"), "a" : 1 }
{ "_id" : ObjectId("5a98b9641435c363f9c06870"), "a" : 2 }
{ "_id" : ObjectId("5a98b9641435c363f9c06871"), "a" : 3 }
{ "_id" : ObjectId("5a98b9641435c363f9c06872"), "a" : 4, "d" : 4 }
{ "_id" : ObjectId("5a98b9641435c363f9c06873"), "a" : 4, "d" : 5 }

删除a>2并且d=4的文档

db.collection.deleteMany({"a":{$gt:2},"d":4})
{ "acknowledged" : true, "deletedCount" : 1 }

删除语法可以大致总结为:db.collection.deleteMany({field1:condition},{field2:condition}…),对所有的delete方法都是适用的
3)db.collection.deleteOne(new Document(), condition)删除满足条件
的第一个文本

db.collection.deleteOne({"a":1})
{ "acknowledged" : true, "deletedCount" : 1 }

删除成功以后都会返回成功删除数据的条数
4)db.collection.remove()删除一个或多个满足条件的文本

db.collection.remove({})
WriteResult({ "nRemoved" : 17 })
test:PRIMARY> db.collection.count()
0

删除所有数据
condition:
3.update:
db.collection.updateMany()更新满足条件的所有文本
首先得在集合中插入足够多的数据,这里我们使用mongodb官方文档提供的数据:

db.inventory.insertMany( [
...    { item: "canvas", qty: 100, size: { h: 28, w: 35.5, uom: "cm" }, status: "A" },
...    { item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
...    { item: "mat", qty: 85, size: { h: 27.9, w: 35.5, uom: "cm" }, status: "A" },
...    { item: "mousepad", qty: 25, size: { h: 19, w: 22.85, uom: "cm" }, status: "P" },
...    { item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "P" },
...    { item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
...    { item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
...    { item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" },
...    { item: "sketchbook", qty: 80, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
...    { item: "sketch pad", qty: 95, size: { h: 22.85, w: 30.5, uom: "cm" }, status: "A" }
... ] );

在inventory集合中插入多条数据
updateMany()方法会更新所有符合条件的文本
eg:

db.inventory.updateMany(
    {"qty":{$lt:50}},
    {$set:{"size.uom":"in","status":"p"},
    $currentDate:{lastModified:true}}
)
{ "acknowledged" : true, "matchedCount" : 3, "modifiedCount" : 3 }

这条语句会更新所有qty<50的文本,对文本中的size.uom和status的内容进行修改
$currentDate会更新lastModified字段的值,如果这个字段不存在,则会创建这个字段
更新成功以后,会返回成功更改文本的数量
db.collection.updateOne()更新满足条件的第一个文本
db.collection.update()
$set对指定字段的值进行替换
数据库中的一条数据:

{ "_id" : ObjectId("5a9d255f824f61fbe944a70e"), "name" : "lele", "age" : 17 }

将"name":“lele"修改为"name”:“lala”
eg:

db.test_collection.update({"name":"lele"},{$set:{"name":"lala"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

基本语法:

db.collection.update({field:value},{$set:{field:value1}})

db.collection.replaceOne()也可以起到update的效果
注:updateOne()、updateMany()、replaceOne()方法存在upsert字段,如果这个字段为true,那么如果没有一个文本匹配上过滤器,则会在database中插入一条新的数据
4.query
1)db.collection.find({})
这应该是最简单的查询语句了,查询出collection集合中的所有数据,等同于下面的sql语句

select * from table_name

2)db.collection.find({field:value})查询出指定条件的文本
eg:

 db.inventory.find({"item":"mat"})
{ "_id" : ObjectId("5aa4b63d4e8ef96bb530f94c"), "item" : "mat", "qty" : 85, "size" : { "h" : 27.9, "w" : 35.5, "uom" : "cm" }, "status" : "A" }

等同于下面的sql语句:

select * from table_name where field = value

3)db.collection.find({field:{operation:[value1,value2]}})
eg:

db.inventory.find({"status":{$in:["A","D"]}})

找到status为A或者D的文本
等同于下面的sql语句

select * from table_name where field in (value1, value2)

4)范围查找
还是直接上例子吧
example-a:specify and condition

db.inventory.find( { status:"A", "qty":{$lt:90}})

查找出status为A,qty<90的文本
等同于下面的sql语句:

select * from inventory where status = "A" and qty < 90

example-b:specify and condition

db.inventory.find({$or:[{"status":"A"},{"qty":{$lt:30}}]})

查找出status为A或者qty<30的文本
等同于下面的sql语句

select * from inventory where status = "A" or qty < 30

基本语法:
db.collection.find({$or:[{},{}]})
[]里面是可以或的条件

example-c:specify and as well as or condition

db.inventory.find({"status":"A",$or:[{"qty":{$lt:30}},{"item":/^p/}]})

查找出status为A,并且qty<30或者item是p开头的文本
等同于下面的sql语句

select * from inventory where status = "A" and (qty < 30 or item like "p%")

5)db.collection.findOne()
查找出集合中的第一个文本

db.inventory.findOne()
{
        "_id" : ObjectId("5aa4b63d4e8ef96bb530f94a"),
        "item" : "canvas",
        "qty" : 100,
        "size" : {
                "h" : 28,
                "w" : 35.5,
                "uom" : "cm"
        },
        "status" : "A"
}

等同于db.collection.find({}).limit(1)

 db.inventory.find({}).limit(1)
{ "_id" : ObjectId("5aa4b63d4e8ef96bb530f94a"), "item" : "canvas", "qty" : 100, "size" : { "h" : 28, "w" : 35.5, "uom" : "cm" }, "status" : "A" }

两者的区别大概就只有查询出的内容排版格式不一样吧
6)查询嵌入式文本
假设collection中有这样一条数据

{ "_id" : ObjectId("5aa4b63d4e8ef96bb530f952"), "item" : "sketchbook", "qty" : 80, "size" : { "h" : 14, "w" : 21, "uom" : "cm" }, "status" : "A" }

查询size为{ “h” : 14, “w” : 21, “uom” : “cm” }的文本

db.inventory.find({"size":{"h":14,"w":21,"uom":"cm"}})

h、w、uom的顺序必须和collection中的顺序一致
如下查询语句

db.inventory.find({"size":{"w":21,"h":14,"uom":"cm"}})

查询内容为空

查询size中uom为in的文本

db.inventory.find({"size.uom":"in"})

通过.访问复合文本中的具体字段
语法大致可以概括为:db.collection.find({field1.field2:value})或者是范围查询db.collection.find({field1.field2:condition})
eg:

db.inventory.find({"size.h":{$lt:15}})

condition可以是and、or、and和or的组合
7)查询数组
为了测试查询数组,我们在inventory中插入如下数据

db.inventory.insertMany([
   { item: "journal", qty: 25, tags: ["blank", "red"], dim_cm: [ 14, 21 ] },
   { item: "notebook", qty: 50, tags: ["red", "blank"], dim_cm: [ 14, 21 ] },
   { item: "paper", qty: 100, tags: ["red", "blank", "plain"], dim_cm: [ 14, 21 ] },
   { item: "planner", qty: 75, tags: ["blank", "red"], dim_cm: [ 22.85, 30 ] },
   { item: "postcard", qty: 45, tags: ["blue"], dim_cm: [ 10, 15.25 ] }
]);

example-a:match an array
eg:

db.inventory.find({"tags":["red","blank"]})

将查询出tag:[red,blank]的文本,可以看作是精确查找
注意到插入的数据中tags内容为tags: [“blank”, “red”],tags: [“red”, “blank”]的文本,查询时是根据顺序来的,如果不想根据顺序,想将只要tags中包含blank和red的文本查询出来,可以通过$all来忽略顺序
eg:

db.inventory.find({"tags":{$all:["red","blank"]}})
{ "_id" : ObjectId("5aa4d4a04e8ef96bb530f954"), "item" : "journal", "qty" : 25, "tags" : [ "blank", "red" ], "dim_cm" : [ 14, 21 ] }
{ "_id" : ObjectId("5aa4d4a04e8ef96bb530f955"), "item" : "notebook", "qty" : 50, "tags" : [ "red", "blank" ], "dim_cm" : [ 14, 21 ] }
{ "_id" : ObjectId("5aa4d4a04e8ef96bb530f956"), "item" : "paper", "qty" : 100, "tags" : [ "red", "blank", "plain" ], "dim_cm" : [ 14, 21 ] }
{ "_id" : ObjectId("5aa4d4a04e8ef96bb530f957"), "item" : "planner", "qty" : 75, "tags" : [ "blank", "red" ], "dim_cm" : [ 22.85, 30 ] }

example-b:query an array for an element
查询出只要数组中还有指定内容的文本
eg:

 db.inventory.find({"tags":"red"})

查询出inventory中tags数组含有red字段的文本
基本语法大概如下:
db.inventory.find({array_field:value})

example-c:query for an element by the array index position
查询数组时,可以通过下标去指定数组中第几个元素应该满足的条件
eg:

db.inventory.find({ "dim_cm.1": { $gt:25}})

这条语句将查询出dim_cm数组中第二个元素>=30的文本

example-d:query an array by array length
查询出满足指定数组长度的文本
eg:

db.inventory.find({"tags":{$size:3}})

查询出tags数组长度为3的文本

example-e:Query an Array with Compound Filter on the Array Elements
eg:

db.inventory.find({"dim_cm":{$gt:15,$lt:20}})
{ "_id" : ObjectId("5aa500a24e8ef96bb530f95e"), "item" : "journal", "qty" : 25, "tags" : [ "blank", "red" ], "dim_cm" : [ 14, 21 ] }
{ "_id" : ObjectId("5aa500a24e8ef96bb530f95f"), "item" : "notebook", "qty" : 50, "tags" : [ "red", "blank" ], "dim_cm" : [ 14, 21 ] }
{ "_id" : ObjectId("5aa500a24e8ef96bb530f960"), "item" : "paper", "qty" : 100, "tags" : [ "red", "blank", "plain" ], "dim_cm" : [ 14, 21 ] }
{ "_id" : ObjectId("5aa500a24e8ef96bb530f962"), "item" : "postcard", "qty" : 45, "tags" : [ "blue" ], "dim_cm" : [ 10, 15.25 ] }

只要数组中有一个元素15,或者有一个元素小于20,或者有一个元素大于15并且小于20,这个文本就会被查询出来

example-f:Query for an Element by the Array Index Position
eg:

db.inventory.find({"dim_cm":{$elemMatch:{$gt:15,$lt:20}}})
{ "_id" : ObjectId("5aa500a24e8ef96bb530f962"), "item" : "postcard", "qty" : 45, "tags" : [ "blue" ], "dim_cm" : [ 10, 15.25 ] }

只有数组中有一个大于15并且小于20的元素,这个文本就会被查询出来
example-e和example-f的唯一区别是数组中的元素是否需要同时满足两个条件

8)查询返回指定字段
example-a return the specified fields and the _id field only
eg:

db.inventory.find({"status":"A"},{"item":1,"status":1})

返回item、status和 _id字段
等同于下面的sql语句

select item, status, _id from inventory where status = "A"  

基本语法大致如下:

db.collection.find({field:value},{field1:1,field2:1})

example-b:suppress _id field
eg:

db.inventory.find({"status":"A"},{"item":-1,"status":1,_id:0})

通过指定_id:0将不会将_id字段返回回来
等同于下面的sql语句:

select item, status from inventory where status = "A"  

基本语法大致如下:

db.collection.find({field:value},{field:1, _id:0})

example-c:return all but the excluded fields
eg:

db.inventory.find({"status":"A"},{"status":0,"instock":0})

返回文本中的所有字段除了被指定为0的字段
基本语法大致如下:

db.collection.find({field:value},{field1:0,field2:0})

example-d:project specific array elements in the returned array
eg:

db.inventory.find({"status":"A"},{"item":1,"status":1,"instock":{$slice:-1}})

通过使用$slice,将会返回item、status、_id、instock数组最后一个元素的内容

9)查询null或者缺少的字段
插入数据:

db.inventory.insertMany([
   { _id: 1, item: null },
   { _id: 2 }
])

eg:

 db.inventory.find({"item":null})

将会查询出item为null或者不存在item字段的文本

eg:

db.inventory.find({"item":{$exists:false}})

返回不存在item字段的文本

eg:

 db.inventory.find({"item":{$type:10}})

返回item字段为null的文本
$type:10代表bson type中的null值
所以想要查询出某个字段为null的文本的正确语法为

db.collection.find({"field":{$type:10}})

而不是直接用null

你可能感兴趣的:(数据库)