征服 Mongodb 之 Modifier初识

本以为Mongodb的CRUD就是些常规操作,其实不然,针对字段、数组的操作还有很多特定指令——修改器。实在是不知道该如何对这一对$符号开始的指令给个靠谱的名称。 

集群配置相关链接:

征服 Mongodb 之 安装与系统服务配置

征服 Mongodb 之 主从复制&集群复制

基本操作相关链接:

征服 Mongodb 之 常用命令、基本数据类型  

征服 Mongodb 之 Modifier初识

征服 Mongodb 之 Modifier增强

征服 Mongodb 之 CRUD

   在Mongodb中,有很多被称为Modifier的特殊标识符。通过这些Modifier,可以增加查询条件限定,对数据进行特定变更,实现像常规数据库的的特定条件更新与查询。

   这里会介绍$inc、$set、$unset、$push、$pull、$ne$addToSet、$each的相关实现,主要用于更新操作。详见:http://cn.docs.mongodb.org/manual/reference/operator/

    一、字段操作——$inc、$set、$unset

    接下来的内容主要是针对Update操作的各种补充。微笑

    $inc、$set、$unset 都是针对字段的操作

  • $inc

    即,Increase,就是递增(递减)。

    我们先看这条数据:

> db.user.find()
{ "_id" : ObjectId("50fe4f627252799620eee0db"), "_class" : "org.zlex.mongodb.domain.User", "uid" : "u1234567890", "address" : "上海", "age" : 1 }

   对age做递增:

> db.user.update({"uid" : "u1234567890"},{"$inc":{"age":1}})
> db.user.find()
{ "_class" : "org.zlex.mongodb.domain.User", "_id" : ObjectId("50fe4f627252799620eee0db"), "address" : "上海", "age" : 2, "uid" : "u1234567890" } 

   对age做递减:

> db.user.update({"uid" : "u1234567890"},{"$inc":{"age":-1}})
> db.user.find()
{ "_class" : "org.zlex.mongodb.domain.User", "_id" : ObjectId("50fe4f627252799620eee0db"), "address" : "上海", "age" : 1, "uid" : "u1234567890" }

    备注:$inc只能用于数字增减操作

  • $set & $unset

    与$inc相比,$set就是一个完全覆盖的指令,$unset是删除某个字段。

    参考上例,把年龄直接置为30:

> db.user.update({"uid" : "u1234567890"},{"$set":{"age":30}})
> db.user.find()
{ "_class" : "org.zlex.mongodb.domain.User", "_id" : ObjectId("50fe4f627252799620eee0db"), "address" : "上海", "age" : 30, "uid" : "u1234567890" }

    干掉age这个字段:

> db.user.update({"uid" : "u1234567890"},{"$unset":{"age":1}})
> db.user.find()
{ "_class" : "org.zlex.mongodb.domain.User", "_id" : ObjectId("50fe4f627252799620eee0db"), "address" : "上海", "uid" : "u1234567890" }

    至于age这后面跟着是个什么值无挂紧要了。不过这名字起的($set & $unset),实在是让人有点迷惑。天真

   二、数组操作—$push、$pull、$addToSet

  • $push & $pull 

     这两个指令用于数组操作,追加元素 & 删除元素。

     向上述数据中追加comments数组:

> db.user.update({"uid" : "u1234567890"},{ $push : {"comments" : {"name":"zlex"}}})
> db.user.update({"uid" : "u1234567890"},{ $push : {"comments" : {"email":"[email protected]","birthday":new Date()} } })
> db.user.find()
{ "_class" : "org.zlex.mongodb.domain.User", "_id" : ObjectId("50fe4f627252799620eee0db"), "address" : "上海", "age" : 30, "comments" : [   {       "name" : "zlex" },      {       "email" : "[email protected]",   "birthday" : ISODate("2013-02-06T02:12:27.869Z") } ], "uid" : "u1234567890" }

    上述数据中,comments数组中有两个元素{ "name" : "zlex" } 和 { "email" : "[email protected]", "birthday" : ISODate("2013-02-06T02:12:27.869Z") }

  我们可以通过$pull,删除某一个元素:

> db.user.update({"uid" : "u1234567890"},{ $pull : {"comments" : {"name":"zlex"}}})
> db.user.find()
{ "_class" : "org.zlex.mongodb.domain.User", "_id" : ObjectId("50fe4f627252799620eee0db"), "address" : "上海", "age" : 30, "comments" : [   {       "email" : "[email protected]",   "birthday" : ISODate("2013-02-06T02:12:27.869Z") } ], "uid" : "u1234567890" }

 通过{ $pull : {"comments" : {"name":"zlex"}}}定位到数组的具体元素。当然也可以根据数组元素的部分信息进行定位删除元素:

> db.user.update({"uid" : "u1234567890"},{ $pull : {"comments" : {"email":"[email protected]"}}})
> db.user.find()
{ "_class" : "org.zlex.mongodb.domain.User", "_id" : ObjectId("50fe4f627252799620eee0db"), "address" : "上海", "age" : 30, "comments" : [ ], "uid" : "u1234567890" }

    不得不说,mongodb的自带查询功能很强大!吐舌头

  • $ne & $addToSet 

   $ne——not exist,即当所属条件不存在时,查询时也会用到

   $addToSet——add to set,即避免重复的追加

   会有这样一种情况,当一个值不在数组中时将其插入,这就需要用到$ne和$push。

> db.user.update({"uid" : "u1234567890"},{ $push : {"comments" : {"email":"[email protected]","birthday":new Date()} } })
> db.user.find()
{ "_class" : "org.zlex.mongodb.domain.User", "_id" : ObjectId("50fe4f627252799620eee0db"), "address" : "上海", "age" : 30, "comments" : [   {       "email" : "[email protected]",   "birthday" : ISODate("2013-02-06T03:06:00.866Z") },     {       "email" : "[email protected]",       "birthday" : ISODate("2013-02-06T03:06:15.675Z") } ], "uid" : "u1234567890" }

   如上述操作,造成了重复数据,可通过$ne指令避免:

> db.user.update({"uid" : {"$ne" :"u1234567890"}},{ $push : {"comments" : {"email":"[email protected]","birthday":new Date()} } })
> db.user.find()
{ "_class" : "org.zlex.mongodb.domain.User", "_id" : ObjectId("50fe4f627252799620eee0db"), "address" : "上海", "age" : 30, "comments" : [   {       "email" : "[email protected]",   "birthday" : ISODate("2013-02-06T03:06:00.866Z") } ], "uid" : "u1234567890" }

   其实就是忽略了符合{"uid" : "u1234567890"}条件的数据更新。

    使用$addToSet可以避免添加重复数据。

    先通过$push向数组追加一组数据:

> db.user.find()
{ "_class" : "org.zlex.mongodb.domain.User", "_id" : ObjectId("50fe4f627252799620eee0db"), "address" : "上海", "age" : 30, "uid" : "u1234567890" }
> db.user.update({"uid" : "u1234567890"},{ $push :{"email":"[email protected]"} })
> db.user.update({"uid" : "u1234567890"},{ $push :{"email":"[email protected]"} })
> db.user.find()
{ "_class" : "org.zlex.mongodb.domain.User", "_id" : ObjectId("50fe4f627252799620eee0db"), "address" : "上海", "age" : 30, "email" : [ "[email protected]", "[email protected]" ], "uid" : "u1234567890" }

    这时,向email数组中追加一条已存在的数据分别用$push$addToSet操作.

    $push :

> db.user.update({"uid" : "u1234567890"},{ $push :{"email":"[email protected]"} })
> db.user.find()
{ "_class" : "org.zlex.mongodb.domain.User", "_id" : ObjectId("50fe4f627252799620eee0db"), "address" : "上海", "age" : 30, "email" : [ "[email protected]", "[email protected]", "[email protected]" ], "uid" : "u1234567890" }

    这时数据有重复("email" : [ "[email protected]", "[email protected]", "[email protected]" ])。

    

    $addToSet :

> db.user.update({"uid" : "u1234567890"},{ $addToSet :{"email":"[email protected]" } })
> db.user.find()
{ "_class" : "org.zlex.mongodb.domain.User", "_id" : ObjectId("50fe4f627252799620eee0db"), "address" : "上海", "age" : 30, "email" : [ "[email protected]", "[email protected]", "[email protected]" ], "uid" : "u1234567890" }

    数据未重复。

    如果想要一次插入多条数据,且数据不重复,可以用$addToSet & $each联合操作。

    先清理email字段,并置一个默认值:

> db.user.update({"uid" : "u1234567890"},{ $unset :{"email":"[email protected]" } })
> db.user.find()
{ "_class" : "org.zlex.mongodb.domain.User", "_id" : ObjectId("50fe4f627252799620eee0db"), "address" : "上海", "age" : 30, "uid" : "u1234567890" }
> db.user.update({"uid" : "u1234567890"},{ $addToSet :{"email":{"$each":["[email protected]"] } }})
> db.user.find()
{ "_class" : "org.zlex.mongodb.domain.User", "_id" : ObjectId("50fe4f627252799620eee0db"), "address" : "上海", "age" : 30, "email" : [ "[email protected]" ], "uid" : "u1234567890" } 

    接着用$addToSet & $each联合操作批量插入数据:

> db.user.update({"uid" : "u1234567890"},{ $addToSet :{"email":{"$each":["[email protected]","[email protected]","[email protected]","[email protected]"] }}})
> db.user.findOne({"uid" : "u1234567890" })
{
        "_class" : "org.zlex.mongodb.domain.User",
        "_id" : ObjectId("50fe4f627252799620eee0db"),
        "address" : "上海",
        "age" : 30,
        "email" : [
                "[email protected]",
                "[email protected]",
                "[email protected]",
                "[email protected]"
        ],
        "uid" : "u1234567890"
}

    数据不重复,OK!

    暂时到此为止,本来想再深入些,但《MongoDB权威指南》的例子实在是有些缺失凌乱,给我造成理解误区。为避免继续混乱下去,我打算先继续后面的研究。犹豫

集群配置相关链接:

征服 Mongodb 之 安装与系统服务配置

征服 Mongodb 之 主从复制&集群复制

基本操作相关链接:

征服 Mongodb 之 常用命令、基本数据类型  

征服 Mongodb 之 Modifier初识

征服 Mongodb 之 Modifier增强

征服 Mongodb 之 CRUD

猜你喜欢

转载自snowolf.iteye.com/blog/1796895