Mongo:笔记二(增删改查)

来源:互联网 发布:淘宝手机修改评价链接 编辑:程序博客网 时间:2024/05/21 14:40


数据库基本操作:增查删改


添加数据

添加数据使用:关键字insertsave

语法格式:

db.collname.insert({…})// 直接插入数据

db.collname.save({…})//如果_id相同则更新


查询数据

查询数据使用:关键字findfindOne(查询一条)

语法格式:

db.collname.find({condition},{field})(不写条件查询所有的数据)

example:

//返回除了age字段外的所有字段

>db.user.find({},{age:0});

//返回tags=tennis除了comments的所有列

db.posts.find({ tags : 'tennis' }, { comments : 0 } );

//返回userid=16name字段

>db.user.find({userid:16},{name:1});

{"_id" : 16, "name" : "user16" }

//返回x=john的所有z字段

db.things.find({ x : "john" }, { z : 1 } );

注:_id字段始终都会被返回,哪怕没有明确指定如果不需要则_id:0即可



条件表达式(类似php魔术方法语法 {方法:参数冒号不可少)


1)<, <=, >, >=

语法:

//大于:field > value db.collection.find({ "field" : { $gt:value } } );

//小于:field< value db.collection.find({ "field" : { $lt: value } });

//大于等于:field >= value db.collection.find({ "field" : { $gte:value } } );

//小于等于:field<=valuedb.collection.find({ "field" : { $lte: value } } );

//大于五小于十db.user.find({_id:{$gt:5,$lte:10}});

//不等于db.user.find({_id:{$ne:10}}).limit(5);


2)$all

$all操作类似$in操作,但是不同的是,$all操作要求数组里面的值全部被包含在返回的记录里面,如:

>db.things.find({a:{$all:[2,3]}});表示查出a字段至少包含23的记录

{"_id" : ObjectId("4de73360059e7f4bdf907cfe"), "a": [ 1, 2, 3 ] }


3)$in

$in操作类似于传统关系数据库中的IN,看例子:

>db.user.find({_id:{$in:[2,3,4,5,1111]}}).limit(5);


4)$nin

$nin$in操作相反,看例子:

//扣掉_id=1/2/3/4的记录

>db.user.find({_id:{$nin:[1,2,3,4]}}).limit(5);


5)$or (外层)  语法{$or: [{_id:2}, {name:'user3'}]}

>db.user.find({$or:[{_id:2},{name:'user3'},{userid:4}]}).limit(5);


6)$nor (外层)  语法{$nor: [{_id:2}, {name:'user3'}]}

$nor$or相反,不好解释,看例子:

>db.user.find({$nor:[{_id:2},{name:'user3'},{userid:4}]}).limit(5);

表示查出id不等于2name不等于user3userid不等于4…


7)$mod 语法{$mod: [除数, 余数]}

$mod操作可以让我们简单的进行取模操作,而不需要用到where子句,如:

//where子句

>db.user.find("this._id%10==1").limit(5);

//$mod操作

>db.user.find({_id:{$mod:[10,1]}}).limit(5);


8)$exists

$exists操作检查一个字段是否存在,如:

>db.user.find({_id:{$exists:true}}).limit(5);


9)$size

$size操作将会查询数组长度等于输入参数的数组,例子:

>db.things.find();

{"_id" : ObjectId("4de73360059e7f4bdf907cfe"), "a": [ 1, 2, 3 ] }

>db.things.find({a:{$size:3}});

{"_id" : ObjectId("4de73360059e7f4bdf907cfe"), "a": [ 1, 2, 3 ] }

>db.things.find({a:{$size:2}}); 



10)$where

例子:

db.f.find({$where:function(){return this.age >= 20 && this.age <= 80}}).limit(2)

//同上效果

db.f.find(function(){return this.age >= 20 && this.age <= 80}).limit(2)


2)$type

$type将会根据字段的BSON类型来检索数据,例如:

//返回a是字符串的记录db.f.find({name:{$type:2}})

下表是 BSON 数据类型表格映射: 
Double 1
String 2
Object 3
Array 4
Binary data 5
Object id 7
Boolean 8
Date 9
Null 10
Regular expression 11
JavaScript code 13
Symbol 14
JavaScript code with scope 15
32-bit integer 16
Timestamp 17
64-bit integer 18
Min key 255
Max key 127

3)count

>db.c1.find({}).limit(2).count(0);

10

>db.c1.find({}).limit(2).count(1);

2

4)正则表达式(仅对字符类型有用)

Mongodb同样支持正则表达式进行检索,如:

//检索name属性是以u开头,4结尾的所有用户

>db.user.find({name:/u.*4$/i}).limit(5);

//同样效果的查询语句

>db.user.find({name:{$regex:'u.*4$',$options:'i'}}).limit(5);

配合其他操作一起使用:

>db.user.find({name:{$regex:'u.*4$',$options:'i',$nin:['user4']}}).limit(5);


注意:/^a//^a.*//^a.*$/这三个表达式最后的效果一样,但是后两种查询效率比第一种要低很多,因为后两种表达式会执行扫描整个字符串,然而第一种扫描到第一个字符就停止了

选项:

-i:忽略大小写

-m:起始符^,结束符$对于每一个新行都起作用

-x:忽略空白字符

-s:这个选项从1.9版本后才支持,加上它就可以让“.”表示所有字符了,包括换行符,例如/a.*b/不匹配"apple\nbanana",但是/a.*b/s可以


5)排序

Mongodb支持排序,例如,按照last_name属性进行升序排序返回所有文档:

//1表示升序,-1表示降序

db.f.find({}).sort({_id:-1})


6)Group (只可单用)

语法:

db.coll.group(

{cond: {filedconditions},

key:{filed: true} ,

initial:{count: 0, total_time:0} ,

reduce:function(doc, out){ } ,

finalize:function(out){} }

);

参数说明:

Cond:查询条件

Key:对那个字段进行Group

Initial:初始化group计数器(开始前的操作)

Reduce:通常做统计操作   (过程中的操作)

Finalize:通常都统计结果进行进一步操作,例如求平均值  (结束后的操作)

Keyf:用一个函数来返回一个替代KEY的值

例子:

db.f.group({

    cond:{age:{$gte:10}},

    key:{name:true},

    initial:{count:0,total_age:0},

    reduce:function(doc,out){out.count++;out.total_age+=doc.age},

    finalize:function(out){out.total_age/out.count}

})

[

        {
"name" : "user10",
"count" : 1,
"total_age" : 100
}

]


7)Distinct (只可单用)

类似于关系数据库中的Distinct,如:

>db.addresses.distinct("zip-code");

>db.runCommand( { distinct: 'addresses', key: 'zip-code' } )


8)分页查询

Mongodb支持skiplimit命令来进行分页查询,例如:

//跳过前10条记录

>db.user.find().skip(10);

//每页返回8条记录

>db.user.find().limit(8);

//跳过前20条记录,并且每页返回10条记录

>db.user.find().skip(20).limit(8);

//下面这个语句跟上一条一样,只是表达不够清晰

>db.user.find({},{},8,20);


9)$elemMatch

>t.find( { x : { $elemMatch : { a : 1, b : { $gt : 1 } } } } )

{"_id" : ObjectId("4b5783300334000000000aa9"), "x": [ { "a" : 1, "b" : 3 }, 7, { "b" : 99}, { "a" : 11 } ] }

//同样效果

>t.find( { "x.a" : 1, "x.b" : { $gt : 1 } } )

阅读的时候可以看作是点·


10)slaveOk

当我们在replicaset进行检索操作时,默认的路由会选择master机器,当我们需要针对任意的从机进行查询的时候,我们需要开启slaveOk选项。当我们在没有开启salveOk选项的时候,如果进行此操作会报如下错:

***not master and slaveok=false

所以我们要进行如下操作:

rs.slaveOk();// enable querying a secondary

db.users.find(...)


11)Cursors游标及CursorMethods

a)遍历游标

类似传统的关系型数据库,Mongodb也有游标的概念。可以利用游标对查询结果进行遍历,如:

//利用游标遍历检索结果

>var cur = db.user.find().skip(10).limit(8);

>cur.forEach(function(x){print(tojson(x))});


b)skip()

skip()方法指定查询记录从第几条开始返回,如,我要从第10个用户开始返回:

>db.user.find().skip(10);


c)limit()

limit()方法指定查询的时候每页返回的记录数,如,我要查询所有用户,没有返回5条记录:

>db.user.find().limit(5);

注:在shell和大多数驱动中,limit(0)相当于没设置limit


d)snapshot()

snapshot()能够保证已经存在于数据中的数据在返回的时候不会缺少对象、不会有重复记录,但是不能保证在查询过程中新增和记录和被删除的记录也被返回。在返回记录小于1MB的时候,snapshot()效果是最好的。


e)sort()

sort()方法对返回记录集按照指定字段进行排序返回,1表示升序,-1表示降序,如:

>db.user.find().limit(10).sort({userid:1});


f)count()

count()方法返回查询记录的总数目,如:

>db.user.find().count();

1000000

>db.user. count();

1000000

>db.user.find({_id:{$lt:20}}).count();

20


下面这条语句效果一样,但是效率低,而且耗内存大,不建议采用:

>db.user.find({_id:{$lt:20}}).toArray().length;

20

当查询语句用到了skip()limit()方法的时候,默认情况下count()会忽略这些方法,如果想要计算这些方法,需要给count()方法传一个true作为参数,如:

>db.user.find({_id:{$lt:20}}).skip(3).limit(9).count();

20

>db.user.find({_id:{$lt:20}}).skip(3).limit(9).count(true);

9

12)$query/$orderby/$explain

//select * from users where x=3 and y='abc' order by x asc;

>db.users.find( { x : 3, y : "abc" } ).sort({x:1});

//同上

>db.users.find( { $query : { x : 3, y : "abc" }, $orderby :{ x : 1 } } );

//返回执行计划

>db.f.find({$query:{age:30},$explain:1}); 


13)NULL查询

//包含NULL情况的查询 

>db.foo.insert( { x : 1, y : 1 } )

>db.foo.insert( { x : 2, y : "string" } )

>db.foo.insert( { x : 3, y : null } )

>db.foo.insert( { x : 4 } )


//Query #1

>db.foo.find( { "y" : null } )

{"_id" : ObjectId("4dc1975312c677fc83b5629f"), "x": 3, "y" : null }

{"_id" : ObjectId("4dc1975a12c677fc83b562a0"), "x": 4 }


//Query #2

>db.foo.find( { "y" : { $type : 10 } } )

{"_id" : ObjectId("4dc1975312c677fc83b5629f"), "x": 3, "y" : null }


//Query #3

>db.foo.find( { "y" : { $exists : false } } )

{"_id" : ObjectId("4dc1975a12c677fc83b562a0"), "x": 4 }



14)$slice 针对数组字段

db.posts.find({},{comments:{$slice: 5}}) // 5条评论

db.posts.find({},{comments:{$slice: -5}}) //5条评论

db.posts.find({},{comments:{$slice: [20, 10]}}) // skip 20, limit 10

db.posts.find({},{comments:{$slice: [-20, 10]}}) // 20 from end, limit 10



删除数据


删除数据使用:关键字remove

语法格式:

db.collname.remove({条件})(不写条件删除所有记录)

//删除一条记录

>db.stu.remove({_id:17});


建议:删除操作的时候,尽量用_id作为条件

注意:某些情况下,当你在对一个记录执行remove操作的时候,可能会有update操作在这个记录上,这样就可能删除不掉这个记录,如果你觉得这不尽人意,那么你可以在remove操作的时候加上$atomic

db.videos.remove({ rating : { $lt : 3.0 }, $atomic : true } )



修改数据

修改数据使用:关键字update

语法格式:db.collname.update({条件})


1)语法update(criteria, objNew, upsert, multi )

参数说明:

Criteria:查询条件

Objnew:更新内容

Upsert:如果记录已经存在,更新它,否则新增一个记录0

Multi:如果有多个符合条件的记录,全部更新1

注意:默认情况下(0,0),只会更新第一个符合条件的记录


2)save()

//如果存在更新它,如果不存在,新增记录

db.mycollection.save(x);


3)常用操作

1  $inc

语法:{$inc : { field : value } }

功能:把field的值加一个value

>db.f.update({name:'yunduan'},{$inc:{age:10}},0,1)

不存在则增加字段并赋值存在则追加 


2  $set

语法:{$set : { field : value } }

功能:把field的值设置成value,当field不存在时,增加一个字段,类似SQLset操作,value支持所有类型

例子:把上面的age改回到20

>db.user.update({_id:0},{$set:{age:20}});

3  $unset

语法:{$unset : { field : 1} }

功能:删除给定的字段field,从1.3版本以后支持

例子:删除上一步增加的sex字段

>db.user.update({_id:0},{$unset:{sex:1}});


4  $push 加入单个值

语法:{$push : { field : value } }

功能:(用于数组)

如果filed是一个已经存在的数组,那么把value追加给field

如果field原来不存在,那么新增field字段,把value的值赋给field

如果field存在,但是不是一个数组,将会出错;

>db.user.update({_id:0},{$push:{aihao:'football'}});


5  $pushAll  将数组元素一个个加入

语法:{$pushAll : { field : value_array } }

功能:功能同$push,只是这里的value是数组,相当于对数组里的每一个值进行$push操作


6  $pull 弹出符合_value检索条件的素组元素

语法:{$pull : { field : _value } }

功能:如果field是一个数组,那么删除符合_value检索条件的素组元素;如果field是一个已经存在的非数组,那么会报错;(用于数组)


//配合其他操作符使用

>db.user.find({_id:0});

{"_id" : 0, "age" : 20, "aihao" : ["swim", "football" ], "name" : "user0","userid" : 0 }

>db.user.update({_id:0},{$pull:{aihao:{$nin:['swim']}}});

>db.user.find({_id:0});

{"_id" : 0, "age" : 20, "aihao" : ["swim" ], "name" : "user0", "userid": 0 }


7  $pullAll(用于数组)

语法:{$pullAll : { field : value_array } }

功能:同$push类似,只是value的数据类型是一个数组

> db.f.update({name:'yunduan'},{$pullAll:{hobby:[0,1,2,3]}},0,1)


8  $pop

语法:(用于数组)

{$pop : { field : 1 } }

功能:删除数组中最后一个元素

语法:{$pop : { field : -1 } }

功能:删除数组中第一个元素


9  $addToSet

语法:{$addToSet : { field : value } }

功能:(用于数组)

如果filed是一个已经存在的数组,并且value不在其中,那么把value加入到数组

如果filed不存在,那么把value当成一个数组形式赋给field

如果field是一个已经存在的非数组类型,那么将会报错

扩展用法:{$addToSet : { a : { $each : [ 3 , 5 , 6 ] } } }


10  $rename

语法:{$rename : { old_field_name : new_field_name }

功能:重命名指定的字段名称,从1.7.2版本后开始支持例子:给aihao字段重命名为ah

>db.user.update({_id:0},{$rename:{'aihao':'ah'}});


11  $bit

语法:

{$bit: { field : {and : int_value}}}

{$bit: {field : {or : int_value }}}

{$bit: {field : {and : int_value, or : int_value }}}

功能:进行位运算,value的必须整数型。从1.7.5版本后开始支持


4)特殊操作符:$(如同php$this)

$操作符代表查询记录中第一个匹配条件的记录项。

>t.update( {'comments.by':'joe'}, {$inc:{'comments.$.votes':1}},false, true )//这里$代表by

>t.update({x: 2}, {$inc: {"x.$": 1}}, false, true);


注意:在数组中用$配合$unset操作符的时候,效果不是删除匹配的元素,而是把匹配的元素变成了null,如:

>t.insert({x: [1,2,3,4,3,2,3,4]})

>t.find()

{"_id" : ObjectId("4bde2ad3755d00000000710e"), "x": [ 1, 2, 3, 4, 3, 2, 3, 4 ] }

>t.update({x:3}, {$unset:{"x.$":1}})//这里$代表3

>t.find()

{"_id" : ObjectId("4bde2ad3755d00000000710e"), "x": [ 1, 2, null, 4, 3, 2, 3, 4 ] }


Find()返回一个游标当:

Var x = db.c1.find();

X使用到游标尽头时不会输出数据

findOne()返回一个json对象

Varx = db.c1.findOne();

x.sex= “nan”;

db.c1.save(x);可直接保存

0 0