查询选择器
>db.customers.find({age:{$lt:102}})
查询age小于102的数据
$lte表示小于或等于
$gt表示大于
$gte表示大于或等于
>db.customers.find({age:{$lt:120,$gte110}})
查询小于120大于等于110的数据
>db.customers.find({id:{$in:[1,2]}})
返回id在1,2集合中的数据
$nin是一种比较低效的查询选择器,它会进行全表扫描,最好不要用$nin
>db.customers.find({id:{$ne:1}})
$ne表示不等于。单独使用$ne,他也不会利用索引的优势,反而进行全表扫描,最好和其他查询选择器配合使用
>db.customers.find({$or:[{id:11},{age:119}]})
$or表示或运算的选择器,主要用于对两个不同key对应的文档进行连接
$and表示与运算器,对于两个不同的key,要同时满足条件,用法与$or一样
>db.customers.find({id:{$exists:false}})
$exists表示返回包含有某个字段的所有记录或者不包含某个字段的所有记录,上面语句表示返回不包含字段id的
所有记录。为了实现这种需求,还有另外一种可代替的语句db.customers.find({id:null})
>db,customers.find({'detail.age':105})
这是一种嵌套查询,detail字段的值也是一个BSON对象
如果detail键对应的为数组,查询就需要通过定位符'$'查询,如下
>db.customers.find({'detail.$.post':5})
查询投射
>db.customers.find({'detail.1.post':5},{_id:0,id:1,name:1})
此条语句查询只显示id和name字段
>db.customers.find({}).sort({id:-1})
对id的降序进行排序后返回,排序很费时间,对于排序,要确保排序的字段上建立索引,而且排序索引执行计划能
够高效地利用索引
>db.customers.find({}).skip(10).limit(5).sort({id:-1})
这条语句执行的过程是先对结果进行排序,然后跳过10行,返回接下来的5行。如果传递给skip的参数很大,那么查
询语句会大量的扫描,效率低
数组操作
1、精确匹配数组值
>db.customers.find({"Attrivalue":["收腰型","修身型","直筒型"]})
匹配如:{"_id":5,"Attriname":"version","Attrvalue":["收腰型","修身型","直筒型"],"isoptional":1}
2、匹配数组中的一个元素值
>db.customers.find({"Attrivalue":"收腰型"})
则返回值中的符合的所有记录
3、匹配指定位置的元素值
>db.customers.find({"Attrivalue.0":"收腰型"})
它表示返回数组中第0个位置的元素值为“收腰型”的所有记录
4、指定数组索引并匹配嵌套文档中的字段值
如果数组中的元素是文档,查询语句如下:
>db.customers.find({"Attervalue.0.status":2})
返回数组中索引0处,且嵌套文档中status值为2的所有文档。
可以通过投影返回指定的字段值,如下所示
>db.customers.find({"_id":2},{_id:0,statusinfo:1})
返回值如下:
{
"statusinfo":[
{
"status":9,
"desc":"已取消"
},
{
"status":2,
"desc":"已付款"
}
]
}
返回的数组中,信息仍然比较多,要求只返回状态的描述"desc"即可
>db.customers.find({"statusinfo.status":2},{_id:0,"statusinfo.desc":1})
返回值如下:
{
"statusinfo":[{"desc":"已付款"},{"desc":"已发货"}]
}
现实需求可能更挑剔,需要返回当前订单的最新状态(数组中最后一个元素),此时需要专门针对数组投射
的操作符$slice来完成:
>db.customers.find({"_id":2},{"_id":0,"statusinfo":{"$slice":-1},"statusinfo.desc":1})
返回值如下:
{
"statusinfo":[{"desc":"已发货"}]
}
根据时间条件查询,条件必须为时间格式
$not
$not是元条件句,即可以在任何其他条件之上。例如,就拿取模运算符$mod来说,$mod会将查询的
值除以第一个给定值,若余数等于第二个给定值,则返回结果:
>db.users.find({"number":{"$mod":[5,1]}})
上面的查询会返回number值为1、6、11、16等的用户,要想返回2、3、4、5、7、8、9等的用户,就要用$not
>db.users.find({"num":{$not:{$mod:[5,1]}}})
null不仅仅匹配自身,而且匹配不存在的文档。返回缺少这个键的所有文档,所有要想匹配键值为null的文档
,既要检查该值是否为null,还要通过$exists条件判断键值已存在
>db.users.find({"z":{$in:[null],$exists:true}})
正则表达式
>db.users.find({name:/joe/i})
数组查询
$all,找到既有apple,又有banana的。顺序无关紧要
>db.user.find({fruit:{$all:["apple","banana"]}})
$size可以查询指定长度的数组
>db.user.find({fruit:{$size:3}})
一个常见的查询需求就是需要一个长度范围,$size并不能与其他查询子句组合(比如$gt),,但是要完成这种
查询可以通过文档中添加一个size键的方式来实现。每次添加指定数组元素的时候,同时增加size的值。以前的
更新为:
>db.user.update({$push:{fruit:strawberry}})
现在变成下面这样:
>db.user.update({$push:{fruit:strawberry},$inc:{size:1}})
这样就可以像下面一样根据范围查询了
>db.user.find({$size:{$gt:3}})#查询数组长度大于3的数据
$slice返回数组的一个子集合
例如返回数组前10条评论:
>db.user.find(criterla:{coments:{$slice:10}})
返回后10条
>db.user.find(criterla:{coments:{$slice:-10}})
还可以接受指定位置后返回的数量,返回第24个之后的10条元素
db.user.find(criterla,{comments:{$slice:[23,10]}})
嵌套对象查询
>db.user.find({name.first:joe,name.last:schmoe})
嵌套数组查询,$elemMatch模糊命名条件语句
>db.user.find({comments:{$elemMatch:{author:joe,score:{$gte:5}}}})
单字段普通索引
>db.customers.ensureIndex({name:1})
为name字段添加一条索引
执行查询,用索引字段作为查询选贼器,
>db.customers.find({name:"ramda9"}),用到索引的查询,扫描的文档数就很少,如果不用索引,就进行了全表扫描
复合索引
>db.customers.ensuerIndex({name:1,cuntry:1})
执行如下查询语句,才能有效果:
>db.customers.find({name:"lanbo2",country:"Malaysia"})
数组的多键索引
如果为数组创建索引,则默认会对数组每一个元素创建索引
可以创建指定数组中嵌套文档指定的字段为索引
>db.customers.ensuerIndex({"statusinfo.desc":1})
删除上面的复合索引
>db.customers.dropIndex("name_1_country_1")
要注意有些查询可能用不上索引,如使用$ne和$nin表达式等
插入语句
>db.customers.insert()
修改语句
>db.coolection.update(query,update,<upsert>,<multi>)
query参数是一个查询选择器,值类型为document
update参数为需要修改的地方,值类型为document,如果update参数只包含字段选项,没有操作符,则会发生取代性的更改
upsert为一个可选参数,boolean类型,默认值为false,当值为true时,update方法将更新匹配到的记录,如果找不到匹配
的文档,则插入。
multi为一个可选参数,boolean类型,表示是否更新匹配到的多个文档,默认值为false,当为true时,update方法将更新所有匹配
1.更改指定的字段值
>db.goods.update({name:"apple"},{$set:{name:"apple5s"},$inc:{price:4000}})
这个操作将匹配到的第一个文档其中的字段name设为"apple5s",字段price增加4000,其他字段保持不变
2.更改指定地段而其他字段被清除掉,可以先查询出文档,然后再进行操作里面的数据,再替换文档,实现里面局部更新
>db.goods.update({name:"htc"},{name:"htc one"})
匹配到的第一个文档中的字段设为"htc one",文档中出了主键_id字段外,其他字段都被清除
3.更改多个文档中的指定字段
>db.goods.update({name:"surface"},{$set:{price:6999}},{multi:true})
将匹配的所有文档中的字段price设为6999,其他字段不变
4.update找不到匹配的文档时则插入新文档
>db.goods.update({name:"iphone"},{$set:{price:5999}},{upsert:true})
如果匹配不到文档,则插入新的文档
$unset删除指定键
db.user.update({"name":"joe"},{"$unset":{"pwd":1}})#完全删除pwd键
$inc用来增加键的值,如果没有键,则创建。只能作用于整数、长整数或双精度浮点
$push数组修改器,会向已有的数组末尾加入一个元素,要是没有则会创建新的数组
$ne实现如果值不在数组就把它加进去,
>db.user.update({"authors":{"$ne":"richie"}},{$push:{"authorscited":"richie"}})#往数组authors cited添加元素
$addToset也能完成跟$ne一样的事,而且比它更好
>db.user.update({"authors":123423},{"addToset":{"authors cited":"richie"}})#往数组authors cited添加元素
$each与$addToset组合可以添加多个不同的值
>db.user.update({"author":"name"},{"$addToset":{"emails":{"$each":["232","423","23112"]}}})
数组删除元素有两种方法$pop与$pull,pop必须制定位置key,pull可以赛选元素的值
>db.list.update({},{"$pop":{key:1}})
>db.list.update({},{"$pull":{"todo":"laungry"}})
$定位符对数组里面的文档修改数据
>db.list.update({"comment.author":"john"},{"$set":{"comments.$.author":"jim"}})
删除语句
>db.coolection.remove(<query>,<justOne>)
参数query为可选参数,查询选择器,类似关系数据库中的where语句。
jusOne参数也是可选参数,是一个boolean类型的值,表示是否只删除匹配的第一个文档,相当于关系数据库中的limit 1 条件
1、删除匹配的所有文档,但是不会删除集合对应的索引数据
>db.goods.remove({name:"htc"})
2、删除匹配的第一个文档
>db.goods.remove({name:"huawei"},1)
3、删除所有文档,但不会删除索引,但是这种效率低下,最好删除数据集db.goods.drop()删除
>db.goods.remove()
聚合
count返回集合中的文档数量,不论集合有多大,都会很快返回:
>db.zj_user.count()
也可以传递查询,统计查询X结果的数量
>db.zj_user.count({x:1})
distinct用来找出给定键的所有不同的值。使用时必须指定集合和键
>db.zj_user({distinct:people,key,age})
###三层嵌套,更新第三层里面的信息
for y,z in enumerate(db.zj_dpt.find_one({"Fsub_dpt.Fid":Fid[:6]},{"Fsub_dpt":{"$elemMatch":{"Fid":Fid[:6]}},"_id":0})["Fsub_dpt"][0]["Fsub_dpt"]):
if z["Fid"]==Fid:
db.zj_dpt.update({"Fsub_dpt.Fid":Fid[:6]},{"$set":{"Fsub_dpt.$.Fsub_dpt."+str(y)+".Fname":Fname}})