mongoDB中CRUD的深入讲解
前言
今天开始接触非关系型数据库的mongoDB,现在将自己做的笔记发出来,供大家参考,也便于自己以后忘记了可以查看。
首先,mongoDB,是一种数据库,但是又区别与mysql,sqlserver、orcle等关系数据库,在优势上面也略高一筹;至于为什么会这么说呢?很简单,我们来举两个例子:
1.在存储上面,非关系型数据库可以更大规模的存储,打个比方,Facebook用的数据库就是非关系型数据库。
2.运用起来更加流畅也是这个数据库的优点,将分布式的特点发挥到极致。
当我查看官方文档的时候,简直要人命,光是一个插入方法都讲了好几条,脑袋都大了,现在我总结一下每一插入方法的特性
db.collection.insert()
db.collection.insert()向集合插入一个或多个文档.要想插入一个文档,传递一个文档给该方法;要想插入多个文档,就可以采用该方法。
例如
db.users.insert(
[
{name:"bob",age:42,status:"A",},
{name:"ahn",age:22,status:"A",},
{name:"xi",age:34,status:"D",}
]
)
如果插入成功就会返回
WriteResult({"nInserted":3})
如果异常情况,那么就会返回如下咯:
WriteResult({
"nInserted":3,
"writeConcernError":{
"code":64,
"errmsg":"waitingforreplicationtimedoutatshard-a"
}
})
当我们想插入一条数据的时候,采用insert的方法据比较浪费内存,这个时候,我们久采用插入单个的语法db.collection.insertOne()向集合插入单个文档document举个小列子来说明一下。
db.users.insertOne(
{
name:"sue",
age:19,
status:"P"
}
)
有了单个,就肯定会有多个,那么多个又是怎么样的呢?语法都很类似,db.collection.insertMany()这个语法跟上面没有区别嘛,对不对,当然是错的,你想,如果添加的数据是数组里面嵌套数组,前面两个的方法的性能就大打折扣了,影响数据库的性能。废话少说,列子走一波:
db.users.insertMany(
[
{
_id:1,
name:"sue",
age:19,
type:1,
status:"P",
favorites:{artist:"Picasso",food:"pizza"},
finished:[17,3],
badges:["blue","black"],
points:[
{points:85,bonus:20},
{points:85,bonus:10}
]
},
{
_id:2,
name:"bob",
age:42,
type:1,
status:"A",
favorites:{artist:"Miro",food:"meringue"},
finished:[11,25],
badges:["green"],
points:[
{points:85,bonus:20},
{points:64,bonus:12}
]
},
{
_id:3,
name:"ahn",
age:22,
type:2,
status:"A",
favorites:{artist:"Cassatt",food:"cake"},
finished:[6],
badges:["blue","Picasso"],
points:[
{points:81,bonus:8},
{points:55,bonus:20}
]
},
{
_id:4,
name:"xi",
age:34,
type:2,
status:"D",
favorites:{artist:"Chagall",food:"chocolate"},
finished:[5,11],
badges:["Picasso","black"],
points:[
{points:53,bonus:15},
{points:51,bonus:15}
]
},
{
_id:5,
name:"xyz",
age:23,
type:2,
status:"D",
favorites:{artist:"Noguchi",food:"nougat"},
finished:[14,6],
badges:["orange"],
points:[
{points:71,bonus:20}
]
},
{
_id:6,
name:"abc",
age:43,
type:1,
status:"A",
favorites:{food:"pizza",artist:"Picasso"},
finished:[18,12],
badges:["black","blue"],
points:[
{points:78,bonus:8},
{points:57,bonus:7}
]
}
]
)
注意:insertOne()、insertMany()是3.2版本的语法。
既然增了,就得查找,对吧,查找里面呢也有很多小东西,有许多自己自定义查询。
1、查询全部
db.users.find({})等价于db.users.find()
2、指定等于条件
一个queryfilterdocument可以使用
下面的示例从user集合中检索status字段值为“P”或者“D”的所有文档:
db.users.find({status:{$in:["P","D"]}})
3、指定AND条件
复合查询可以在集合文档的多个字段上指定条件。隐含地,一个逻辑的AND连接词会连接复合查询的子句,使得查询选出集合中匹配所有条件的文档。
下面的示例在users集合中检索status等于"A"``**并且**``age小于($lt)30是所有文档:
db.users.find({status:"A",age:{$lt:30}})
4、指定OR条件
通过使用$or操作符,你可以指定一个使用逻辑OR连接词连接各子句的复合查询选择集合中匹配至少一个条件的文档。
下面的示例在users集合中检索status`等于"A"**或者**age小于($lt)30所有文档:
db.users.find(
{
$or:[{status:"A"},{age:{$lt:30}}]
}
)
5、指定AND和OR条件(可以更加精确的查询)
在下面的示例中,复合查询文档选择集合中status``等于"A"并且要么age小于($lt)30要么type等于1的所有文档:
db.users.find(
{
status:"A",
$or:[{age:{$lt:30}},{type:1}]
}
)
6、嵌入文档上的精确匹配
使用{
在下面的例子中,查询匹配所有favorites字段是以该种顺序只包含等于"Picasso"``的``artist和等于"pizza"的food字段的内嵌文档:
db.users.find({favorites:{artist:"Picasso",food:"pizza"}})
7、嵌入文档中字段上的等于匹配
在下面的例子中,查询使用dotnotation匹配所有favorites字段是包含等于"Picasso"的字段``artist``(可能还包含其他字段)的内嵌文档:
db.users.find({"favorites.artist":"Picasso"})
8、数组上的查询
采用一个参数:$elemMatch(该参数是值精确的数组)
下面的例子查询finished数组至少包含一个大于($gt)15并且小于($lt)20的元素的文档:
db.users.find({finished:{$elemMatch:{$gt:15,$lt:20}}})
9、嵌入文档数组
使用数组索引匹配嵌入文档中的字段
在下面的例子中,查询使用thedotnotation匹配所有dadges是第一个元素为”black”的数组的文档:
db.users.find({'points.0.points':{$lte:55}})
10、不指定数组索引匹配字段
如果你不知道文档在数组中的索引位置,用点号(.)将包含数组的字段的名字和内嵌文档的字段的名字连起来。
下面的例子选择出所有points``数组中至少有一个嵌入文档包含值小于或等于``55的字段points的文档:
db.users.find({'points.points':{$lte:55}})
11、指定数组文档的多个查询条件
单个元素满足查询条件
使用$elemMatch操作符为数组元素指定复合条件,以查询数组中至少一个元素满足所有指定条件的文档。
下面的例子查询points数组有至少一个包含points小于等于70并且字段bonus等于20的内嵌文档的文档:
db.users.find({points:{$elemMatch:{points:{$lte:70},bonus:20}}}
12、元素组合满足查询条件
下面的例子查询了points数组包含了以某种组合满足查询条件的元素的文档;例如,一个元素满足points小于等于70的条件并且有另一个元素满足bonus等于20的条件,或者一个元素同时满足两个条件:
db.users.find({"points.points":{$lte:70},"points.bonus":20})
接下来就是更新咯,老样子跟插入方法差不多,更新就可以看做是插入的一种。
来一段官方文档的话:
如果db.collection.update(),db.collection.updateOne(),db.collection.updateMany()或者db.collection.replaceOne()包含upsert:true并且没有文档匹配指定的过滤器,那么此操作会创建一个新文档并插入它。如果有匹配的文档,那么此操作修改或替换匹配的单个或多个文档。
这个解释在我认为就是在没有该数据的时候就会创建相应的数据,毕竟它是插入的一种特殊方法。
1、db.collection.updateOne():修改单条数据
下面的例子对users集合使用db.collection.updateOne()方法来更新第一个根据过滤条件favorites.artist等于“Picasso”匹配到的文档更新操作:
使用$set操作符更新favorites.food字段的值为“pie”并更新type字段的值为3,
db.users.updateOne(
{"favorites.artist":"Picasso"},
{
$set:{"favorites.food":"pie",type:3},
}
)
2、db.collection.update()的用法和db.collection.updateOne()类似,为了区别一下,我们采用了{multi:true}这个参数,这样会在你修改之后的数据中有这个参数,表示修改完成。
db.users.update(
{"favorites.artist":"Pisanello"},
{
$set:{"favorites.food":"pizza",type:0,}
},
{multi:true}
)
3、db.collection.updateMany(),这个会不会认为是修改很多,当然可以这么理解,但是我更喜欢把他理解成修改多个参数。
下面这个举例就是为了大家看的明白采用了{upsert:true},它可以清晰的返回你修改后的值
db.inspectors.updateMany(
{"Sector":{$gt:4},"inspector":"R.Coltrane"},
{$set:{"Patrolling":false}},
{upsert:true}
);
4、修改还有一个就是文档替换db.collection.replaceOne
下面的例子对users集合使用db.collection.replaceOne()方法将通过过滤条件name等于"sue"匹配到的**第一个**文档替换为新文档:
db.users.replaceOne(
{name:"abc"},
{name:"amy",age:34,type:2,status:"P",favorites:{"artist":"Dali",food:"donuts"}}
)
走着,撸删除了:
1、删除所有文档db.collection.remove()
这个方法就干脆了,就相当于sql中的删除表结构的delete()
db.users.remove({})
作为另一种选择如下例子使用db.collection.remove()从users集合中删除所有status字段等于“A”的文档:
db.users.remove({status:"P"})
2、仅删除一个满足条件的文档db.collection.deleteOne()
如下例子使用db.collection.deleteOne()删除第一个status字段等于“A”的文档:
db.users.deleteOne({status:"D"})
3、删除集合中所有文档db.collection.deleteMany()
如下的例子使用db.collection.deleteMany()方法从users集合中删除了所有文档:
db.users.deleteMany({})
以上是通过两天学习官方文达能的总结,下面配上官方文档的地址表示感谢。
https://docs.mongodb.com/manual/reference/method/js-collection/
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对毛票票的支持。