MongoDB 添加、查询(条件查询、排序、分页、返回指定字段)、修改、删除数据、聚合aggregate
MongoDB内部支持JavaScript语法,使用SpiderMonkey作为内部的JavaScript解释器引擎。
MongoDB内部支持JavaScript语法
,使用SpiderMonkey作为内部的JavaScript解释器引擎。
1、常用命令
- show databases:显示数据库列表
- use:切换数据库
- show collections:显示数据库列表
- show users:显示当前数据库的用户列表
- show roles:显示当前数据库的角色列表
连接MongoDB
mongo‐‐host <HOSTNAME> ‐‐port <PORT>
1、添加数据
添加数据并不需要像mysql一样,必须要先创建表
1.1、insertOne/insert单条插入
插入单条数据
db.集合.insertOne(<JSON对象>)
示例:
- 不指定 _id
db.member.insertOne({"name":"张三","age":18,"create":new Date()})
db.member.insert({"name":"李四1","age":18,"create":new Date()})
不指定主键,MongoDB将默认创建一个主键,字段固定为_id,ObjectId 前四个字节代表了主键生成的时间,精确到秒。主键ID在客户端驱动生成,一定程度上代表了顺序性,但不保证顺序性
,可以通过ObjectId(“id值”).getTimestamp() 获取创建时间。
- 指定 _id
db.member.insertOne({"_id":1,"name":"张三","age":18,"create":new Date()})
acknowledged : true,标识插入成功
insertedId:返回创建的id
1.2、insertMany多条插入数据
-
json数组插入多条数据
db.member.insertMany([{"_id":2,"name":"李四","age":18,"create":new Date()},{"_id":3,"name":"王五","age":18,"create":new Date()}])
-
脚本的方式插入多条数据
var names = ['张一','张二']; var members = []; var member ={}; for(var i=0;i<2;i++){ var member ={name:names[i],"age":[i],"create":new Date()}; members.push(member); }; db.member.insertMany(members);
2、查询
2.1、查询全部数据
db.集合名.find()
例如查询:member集合中所有数据
db.member.find()
在mongo shell中默认显示20条数据,输入it命令读取下一批;当在Navicat中会一次性返回;
2.2、指定条件查询
注意find查询条件中是一个对象
- 查询age=18
db.member.find({age:18});
- 查询 _id>2 并且 age =18
db.member.find({_id :{$gt: 2}, age:18});
2.3、排序
sort中对象的值
- -1 是降序
- 1是升序
db.member.find({_id :{$gt: 2}}).sort({_id:-1});
2.4、分页
skip:跳过指定记录数
limit:返回结果数量
db.member.find().skip(1).limit(5);
跳过第1条,一共查询3条数据
2.5、返回指定字段
0代表不显示,1代表显示。
注意:_id默认是显示的,只有_id不显示是设置0,其他字段都不可以设置0
find({查询条件,可以空},{显示的字段:1})
2.6、查询操作符
mongo操作符 | 描述 | 对比mysql |
---|---|---|
$eq | 等值比较,find({_id :{ $eq: 1}}) 等价于 find({_id : 1}) | id = 1 |
$ne | 不等于指定值,find({_id :{ $ne: 1}}) | id != 1 或 id<> 1 |
$in | 数组中包含 ,find( { _id :{ $in: [ 1,2 ] } } ) | id in ( 1,2 ) |
$nin | 数组中不包含,find( { _id :{ $nin: [ 1,2 ] } } ) | id not in ( 1,2 ) |
$gt | 大于指定值,find({_id :{$gt: 1}}) | id > 1 |
$get | 大于等于指定值,find({_id :{$gte: 1}}) | id >= 1 |
$lt | 小于指定值,find({_id :{$lt: 1}}) | id < 1 |
$lte | 小于等于指定值,find({_id :{$lte: 1}}) | id <= 1 |
$and | 与(并且)查询,find({$and:[ { _id:{ $gt:1} },{ _id:{ $lt:4} } ]}) | id > 1 and id < 4 |
$or | 或查询,find({$or:[ { _id:1 },{ _id: 3} ]}) | id = 1 or id= 3 |
$not | 非查询,非小于3的数据 find({_id :{$not :{ $lt: 3 } } }) | id >= 3 |
$nor | 即非查询,find( { $nor: [ { _id: 1 }, { _id: 2 }, { _id: 3 }] } ) | (id != 1 and id !=2 and id !=3) |
$all | 同时包含,查询tag同时包含3和9的数据,tag是一个数组,find({tag:{$all:[3,9]}}),可查看下面示例 | 无 |
$elemMatch | 有一个元素匹配即可,find({job:{$elemMatch:{city:‘beijing’,company:‘xiaomi’}}}),可查看下面示例 | 无 |
$size | 匹配数组大小,find({tag:{$size:3}}),可查看下面示例 | 无 |
$slice | 返回数组中第几个元素,find({job:{KaTeX parse error: Expected 'EOF', got '}' at position 43: …ompany:'baidu'}}̲},{name:1,job:{slice:1}}),可查看下面示例 | 无 |
$exists | 匹配是否包含查询字段的文档,find({name:{$exists:true}}) | 无 |
-
$all查询
db.member.insertMany([{name:"A",tag:[1,2,3],age:18},{name:"B",tag:[3,5,9],age:19}]); db.member.find({tag:{$all:[3,9]}})
-
$elemMatch查询
匹配嵌套数组中至少有一个对象完全匹配db.member.insertMany([{name:"C",job:[{city:"beijing",company:'baidu'},{city:"shenzhen",company:'huawei'}],age:18},{name:"D",job:[{city:"beijing",company:'xiaomi'}],age:19}]) db.member.find({job:{$elemMatch:{city:'beijing',company:'baidu'}}}) db.member.find({job:{$elemMatch:{city:'beijing',company:'huawei'}}}) db.member.find({job:{$elemMatch:{city:'beijing',company:'xiaomi'}}})
-
$size,匹配嵌套的数组大小
-
$slice
- 值 > 0,返回数组的几个元素
- 值 < 0,返回数组的倒数几个元素
3、修改
db.集合.update(query, update, options)
参数说明
- query:更新的查询条件
- update:要更新的内容
- options:更新的选项
操作符
操作符 | 格式 | 描述 |
---|---|---|
$set | { $set : { filed : value} } | 指定一个键,并更新值 |
$unset | { $unset : { filed : 1} } | 删除一个键 |
$inc | { $inc : { filed : value} } | 对数值类型进行增减 |
$push | { $push : { filed : value} } | 将数值追加到数组中,若数组不存在则会进行初始化 |
$pushAll | { $pushAll : { filed : value_array} } | 追加多个值到数组内 |
$pull | { $pull : { filed : value} } | 从数组中删除指定元素 |
$addToSet | { $addToSet : { filed : value} } | 添加元素到数组中,具有排重功能 |
$pop | { $pop : { filed : 1} } | 删除数组第一个或最后一个 |
$rename | { $rename : { old_filed_name : new_filed_name } } | 修改地段名称 |
$bit | { $bit : { filed : {and :5} } } | 位操作,integer类型 |
3.1、更新单个文档
更新_id等于3的名字
db.member.update({_id:3},{$set:{name:‘张五1’}})
db.member.updateOne({_id:3},{$set:{name:‘张五1’}})
3.2、multi更新多个文档
更新多个文档需要设置 multi选项 :true
,默认情况下mongo update命令在更新第一个文档后就返回。
db.member.update({age:19},{$set:{ name:‘zhang1’}},{‘multi’:true});
db.member.updateMany({age:19},{$set:{ name:‘zhang33’}})
3.3、upsert更新的字段不存在则插入
upsert选项为true:如果更新文档不存在则创建文档,如果文档存在字段不存在则创建字段,都存在则更新
db.member.update({_id:3}, { $set:{ address :‘北京’} } ,{upsert:true})
3.4、findAndModify查询和修改
查询并修改指定值,注意先返回结果,后更新,返回的结果是旧数据
db.member.findAndModify({query:{name:‘张1’} , update:{ $set:{ ‘age’:18 } } })
查询并修改指定值,并返回新值
db.member.findAndModify({query:{name:‘张1’} , update:{ $set:{ ‘age’:18 } } })
3.5、count
默认情况下 , count不会考虑 skip 和 limit的效果,如果希望考虑 limit 和 skip ,需要设置 为 true。
分布式环境下,count不保证数据的绝对正确
4、删除数据
4.1、删除单个文档
db.member.deleteOne({_id:2})
remove命令会删除匹配条件的全部文档,删除单个文档,可以根据_id 或者唯一值删除。
db.member.remove({name:‘张1’})
如果希望明确删除一个文档,需要指定justOne参数
db.member.remove({age:19},true)
4.2、删除多个文档
db.member.remove({age:19})
或
db.member.deleteMany({age:19})
4.3 删除全部文档
db.member.remove({})
或
db.member.deleteMany({})
或
db.member.drop()
remove与deleteMany是对查询范围内的数据逐条删除,drop是删除整个集合(包括全部索引)
drop更高效
4.5、删除并返回删除的数据findOneAndDelete
remove和deleteMany只能按照默认顺序删除,并返回确认信息。findOneAndDelete可以指定顺序删除文档和返回删除的内容
删除并返回
db.member.findOneAndDelete({age:18})
删除指定排序的数据
db.member.findOneAndDelete({age:18},{sort:{_id:-1}})
5、聚合
MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。
聚合表达式:
-
获取字段信息
$<field> : 用 $ 指示字段路径,注意使用""
$<field>.<sub field> : 使用 $ 和 . 来指示内嵌文档的路径 -
常量表达式
$literal :<value> : 指示常量 <value> -
系统变量表达式
$$ 使用 $$ 指示系统变量
$$CURRENT 指示管道中当前操作的文档
创建订单数据
db.orders.insertMany(
[
{
orderNo:"000001",
phone:"13101010101",
name:"LiuBei",
status:"created",
shippingFee:10,
orderLines:[
{product:"Huawei Meta30 Pro",sku:"2002",qty:100,price:6000,cost:5599},
{product:"Huawei Meta40 Pro",sku:"2003",qty:10,price:7000,cost:6599},
{product:"Huawei Meta40 5G",sku:"2004",qty:80,price:4000,cost:3700}
]
},
{
orderNo:"000002",
phone:"13101010101",
name:"LiuBei",
status:"created",
shippingFee:10,
orderLines:[
{product:"Huawei Meta30 Pro",sku:"2002",qty:100,price:6200,cost:5699},
{product:"Huawei Meta40 Pro",sku:"2003",qty:10,price:7200,cost:6699},
{product:"Huawei Meta40 5G",sku:"2004",qty:80,price:4200,cost:3800}
]
},
{
orderNo:"000003",
phone:"13101010101",
name:"LiuBei",
status:"created",
shippingFee:10,
orderLines:[
{product:"Huawei Meta30 Pro",sku:"2002",qty:100,price:6400,cost:5799},
{product:"Huawei Meta40 Pro",sku:"2003",qty:10,price:7400,cost:6799},
{product:"Huawei Meta40 5G",sku:"2004",qty:80,price:4400,cost:3900}
]
}
]
);
5.1、统计总数
统计所有订单销售价格和成本价格的总和
db.orders.aggregate([{$addFields: {
totalPrice:{ $sum: "$orderLines.price"},
totalCost: { $sum: "$orderLines.cost"},
}}]).pretty();
$addFields:临时添加字段到返回的文档中
$sum:统计字段的总数
pretty():返回结构化数据
统计所有订单销售价格和成本价格的总和并按照,销售价格totalPrice倒序排列
db.orders.aggregate(
[
{$addFields: {
totalPrice:{ $sum: "$orderLines.price"},
totalCost: { $sum: "$orderLines.cost"},
}
},{
$sort: {
totalPrice: -1
}
}
]).pretty();
- 聚合中方法对应的值必须是集合中的字段例如:$sum: “$orderLines.price”,
嵌套类型使用 $ 和 . 来指示内嵌文档的路径
- 先聚合,再排序
5.2、$project:重命名和隐藏或显示字段
重命名
将name重命名为nickName
db.member.aggregate({KaTeX parse error: Expected '}', got 'EOF' at end of input: …ect:{nickName:'name’}})
隐藏或显示字段
显示_id与name,_id默认显示
db.member.aggregate({$project:{name:1}})
5.3、$match:匹配,同find()一样的参数
db.member.aggregate({$match:{name:‘张5’}})
联合使用
多条件使用
db.member.aggregate({KaTeX parse error: Expected '}', got 'EOF' at end of input: match:{and :[{name:‘张5’},{age:‘185’}]}})
db.member.aggregate({KaTeX parse error: Expected '}', got 'EOF' at end of input: match:{or :[{name:‘张5’},{age:‘186’}]}})
5.4、$limit:限制结果数量
db.member.aggregate({$limit:3})
5.5、$skip:忽略结果的数量
db.member.aggregate({$skip:1})
5.6、$sort:按照给定的字段排序结果
db.member.aggregate({$sort:{_id:1}})
5.7、$group:按照给定表达式组合结果
对于group ,聚合操作主要有以下几种
- $addToSet :将分组中的元素添加到一个数组中,并且自动去重
- $avg 返回分组中的平均值, 非数值直接忽略
- $first 返回分组中的第一个元素
- $last 返回分组中的最后一个元素
- $max 返回分组中的最大元素
- $min 回分组中的最小元素
- $push 创建新的数组,将值添加进去
- $sum 求分组数值元素和
以name分组,统计shippingFee的和
db.orders.aggregate([{$group:{_id:'$name',totlaShippingFee:{$sum:'$shippingFee'}}}])
5.8、$unwind:将数组打平,才分成多条数据
将tag数组拆分成多条数据,并匹配_id等于3的数据
db.member.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: unwind:{path:'tag’}},{$match:{_id:3}}])
将tag数组拆分成多条数据,并匹配_id等于3同时tag等于2的数据
db.member.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: unwind:{path:'tag’}},{KaTeX parse error: Expected '}', got 'EOF' at end of input: match:{and:[{_id:3},{tag:2}]}}])
includeArrayIndex: 显示数组对应的索引值, 赋值给后面指定的字段
db.member.aggregate([{$unwind:{path:'$tag',includeArrayIndex:'tagIndex'}},{$match:{_id:3}}])
NumberLong:标识当前tag的值在原来数组中第一个位置
preserveNullAndEmptyArrays:true
:path对应的字段如果在查询数据中没有,默认是不显示的,设置true则显示,展开时保留空数组,或者不存在数组字段的文档。如图
更多推荐
所有评论(0)