博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MongoDB修改器和pymongo
阅读量:5292 次
发布时间:2019-06-14

本文共 15840 字,大约阅读时间需要 52 分钟。

MongoDB修改器

在mongodb中通常文档只会有一部分要更新,利用原子的更新修改器,可以做到只更新文档的一部分键值,而且更新极为高效,更新修改器是种特殊的键,用来指定复杂的更新操作,比如调整、增加、或者删除键,还可以操作数组和内嵌文档。增加、修改或删除键的时候,应该使用$修改器

1. $set修改器

  $set修改器用来指定一个键值. 如果这个键不存在, 则创建它,它对于更新模式或者用户定义键来说很方便.

> db.users.findOne(){        "_id" : ObjectId("56fe7df8b322e3ff1dabf834"),        "name" : "joe",        "age" : 30,        "sex" : "male",        "location" : "Wisconsin",        "favorite book" : "war and pace"}> db.users.update({
"name":"joe"},{
"$set":{
"favorite book":["cat's cardle","foundation trilogy","ender's game"]}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.users.findOne(){ "_id" : ObjectId("56fe7df8b322e3ff1dabf834"), "name" : "joe", "age" : 30, "sex" : "male", "location" : "Wisconsin", "favorite book" : [ "cat's cardle", "foundation trilogy", "ender's game" ]}

2. $set用来修改内嵌文档

> db.blog.insert({
"title":"a blog post","author":{
"name":"joe","email":"joe@example.com"}})WriteResult({ "nInserted" : 1 })> db.blog.findOne(){ "_id" : ObjectId("57709da84f533aa7535d46d3"), "title" : "a blog post", "author" : { "name" : "joe", "email" : "joe@example.com" }}> db.blog.update({
"author.name":"joe"},{
"$set":{
"author.name":"joe schmoe"}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.blog.findOne(){ "_id" : ObjectId("57709da84f533aa7535d46d3"), "title" : "a blog post", "author" : { "name" : "joe schmoe", "email" : "joe@example.com" }}> db.blog.update({
"title":"a blog post"},{
"$set":{
"author.name":"joe schmoe op"}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.blog.findOne(){ "_id" : ObjectId("57709da84f533aa7535d46d3"), "title" : "a blog post", "author" : { "name" : "joe schmoe op", "email" : "joe@example.com" }}

3. $unset修改器

  $unset修改用于将键删除

> db.users.findOne(){        "_id" : ObjectId("56fe7df8b322e3ff1dabf834"),        "name" : "joe",        "age" : 30,        "sex" : "male",        "location" : "Wisconsin",        "favorite book" : [                "cat's cardle",                "foundation trilogy",                "ender's game"        ]}> db.users.update({
"name":"joe"},{
"$unset":{
"favorite book":1}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.users.findOne(){ "_id" : ObjectId("56fe7df8b322e3ff1dabf834"), "name" : "joe", "age" : 30, "sex" : "male", "location" : "Wisconsin"}

4. $inc修改器

  $inc其用来增加或减少已有的键的键值,或者在键不存在的时候创建一个键。

> db.games.insert({
"game":"pinball","user":"joe"})WriteResult({ "nInserted" : 1 })> db.games.findOne(){ "_id" : ObjectId("5770a1394f533aa7535d46d4"), "game" : "pinball", "user" : "joe"}> db.games.update({
"game":"pinball","user":"joe"},{
"$inc":{
"score":50}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.games.findOne(){ "_id" : ObjectId("5770a1394f533aa7535d46d4"), "game" : "pinball", "user" : "joe", "score" : 50}

  为"score"键增加50再减少20

> db.games.update({
"game":"pinball","user":"joe"},{
"$inc":{
"score":50}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.games.findOne(){ "_id" : ObjectId("5770a1394f533aa7535d46d4"), "game" : "pinball", "user" : "joe", "score" : 100}> db.games.update({
"game":"pinball","user":"joe"},{
"$inc":{
"score":-20}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.games.findOne(){ "_id" : ObjectId("5770a1394f533aa7535d46d4"), "game" : "pinball", "user" : "joe", "score" : 80}

  以上"$inc"与"$set"的用法类似,就是专门用来增加或减少数字的。"$inc"只能用于整数、长整数或双精度浮点数,要是在其他类型的数据上就会导致操作失败,其中包括很多语言会自动转换成数字的类型,例如null,布尔类型,或数字构成的字符串。"$inc"键的值必须为数字,不能使用字符串、数组和其他非数字的值,否则会报错,要修改其他类型,只能使用"$set"。

> db.foo.insert({
"count":"1"})WriteResult({ "nInserted" : 1 })> db.foo.find(){ "_id" : ObjectId("5770befc4f533aa7535d46d5"), "count" : "1" }> db.foo.update({},{
"$inc":{
"count":1}})WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0, "writeError" : { "code" : 16837, "errmsg" : "Cannot apply $inc to a value of non-numeric type. {_id: ObjectId('5770befc4f533aa7535d46d5')} has the field 'count' of non-numeric type String" }})> db.foo.update({},{$set:{count:2}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.foo.find(){ "_id" : ObjectId("5770befc4f533aa7535d46d5"), "count" : 2 }>

5. 数组修改器 $push

  数组修改器,顾名思义它只可以用于操作数组,只能用在值为数组的键上。$push修改器如果指定的值已经存在,"$push"会想已有的数组末尾加入一个元素,要是没有就会创建一个新的数组

> db.blog.findOne(){        "_id" : ObjectId("57709da84f533aa7535d46d3"),        "title" : "a blog post",        "author" : {                "name" : "joe schmoe op",                "email" : "joe@example.com"        }}> db.blog.update({
"title":"a blog post"},{
"$unset":{
"author":1}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.blog.findOne(){ "_id" : ObjectId("57709da84f533aa7535d46d3"), "title" : "a blog post" }> db.blog.update({
"title":"a blog post"},{
"$push":{
"comments":{
"name":"joe","email":"joe@example.com","content":"nice post"}}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.blog.findOne(){ "_id" : ObjectId("57709da84f533aa7535d46d3"), "title" : "a blog post", "comments" : [ { "name" : "joe", "email" : "joe@example.com", "content" : "nice post" } ]}

6. 数组修改器 $ne

  $ne也是用来操作数组的修改器,在查询文档中,如果一个值不在数组里面就把他加进去,如果在不添加

> db.users.insert({
"name":"joe","emails":["joe@example.com","joe@gmail.com","joe@yahoo.com"]})WriteResult({ "nInserted" : 1 })> db.users.findOne(){ "_id" : ObjectId("5770ca42e90c1adc80040a08"), "name" : "joe", "emails" : [ "joe@example.com", "joe@gmail.com", "joe@yahoo.com" ]}> db.users.update({
"name":"joe","emails":{$ne:"joe@gmail.com"}},{$push:{
"emails":"joe@gmail.com"}})WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 }) --nMatched为0表示没有修改> db.users.update({
"name":"joe","emails":{$ne:"joe@itpub.com"}},{$push:{
"emails":"joe@itpub.com"}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.users.findOne(){ "_id" : ObjectId("5770ca42e90c1adc80040a08"), "name" : "joe", "emails" : [ "joe@example.com", "joe@gmail.com", "joe@yahoo.com", "joe@itpub.com" ]}

  以上这种方式也可以使用$addToSet实现。

7. 数组修改器 $addToSet

  $addToSet也是用来操作数组的修改器,实现的功能与$ne修改器相同,且更为方便。使用$addToSet修改器可以避免重复

> db.users.findOne(){        "_id" : ObjectId("5770ca42e90c1adc80040a08"),        "name" : "joe",        "emails" : [                "joe@example.com",                "joe@gmail.com",                "joe@yahoo.com",                "joe@itpub.com"        ]}> db.users.update({
"_id":ObjectId("5770ca42e90c1adc80040a08")},{$addToSet:{
"emails":"joe@gmail.com"}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 }) --原文档里已有"joe@gmail.com",修改完也没有产生重复值> db.users.findOne(){ "_id" : ObjectId("5770ca42e90c1adc80040a08"), "name" : "joe", "emails" : [ "joe@example.com", "joe@gmail.com", "joe@yahoo.com", "joe@itpub.com" ]}> db.users.update({
"_id":ObjectId("5770ca42e90c1adc80040a08")},{$addToSet:{
"emails":"joe@163.com"}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.users.findOne(){ "_id" : ObjectId("5770ca42e90c1adc80040a08"), "name" : "joe", "emails" : [ "joe@example.com", "joe@gmail.com", "joe@yahoo.com", "joe@itpub.com", "joe@163.com" ]}

8. 数组修改器 $each

  $each数组修改器要和$addToSet修改结合起来用,可以一次添加多个不同的值。例如上面的例子中,我们一次添加多个email值, 如下:

> db.users.findOne(){        "_id" : ObjectId("5770ca42e90c1adc80040a08"),        "name" : "joe",        "emails" : [                "joe@example.com",                "joe@gmail.com",                "joe@yahoo.com",                "joe@itpub.com",                "joe@163.com"        ]}> db.users.update({
"_id":ObjectId("5770ca42e90c1adc80040a08")},{$addToSet:{$each:["joe@example.com","joe@python.com","joe@php.com"]}})WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0, "writeError" : { "code" : 52, "errmsg" : "The dollar ($) prefixed field '$each' in '$each' is not valid for storage." }})> db.users.update({
"_id":ObjectId("5770ca42e90c1adc80040a08")},{$addToSet:{
"emails":{$each:["joe@example.com","joe@python.com","joe@php.com"]}}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.users.findOne(){ "_id" : ObjectId("5770ca42e90c1adc80040a08"), "name" : "joe", "emails" : [ "joe@example.com", "joe@gmail.com", "joe@yahoo.com", "joe@itpub.com", "joe@163.com", "joe@python.com", "joe@php.com" ]}

9. 数组修改器 $pop

  $pop修改器主要于从数组中删除元素,他可以从数组中的任何一端删除元素,

例如:
  {$pop:{key:1}} 从数组末尾删除一个元素
  {$pop:{key:-1}} 从数组头部删除一个元素

> db.users.findOne(){        "_id" : ObjectId("5770ca42e90c1adc80040a08"),        "name" : "joe",        "emails" : [                "joe@example.com",                "joe@gmail.com",                "joe@yahoo.com",                "joe@itpub.com",                "joe@163.com",                "joe@python.com",                "joe@php.com"        ]}> db.users.update({
"name":"joe"},{$pop:{
"emails":1}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.users.findOne(){ "_id" : ObjectId("5770ca42e90c1adc80040a08"), "name" : "joe", "emails" : [ "joe@example.com", "joe@gmail.com", "joe@yahoo.com", "joe@itpub.com", "joe@163.com", "joe@python.com" ]}> db.users.update({
"name":"joe"},{$pop:{
"emails":-1}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.users.findOne(){ "_id" : ObjectId("5770ca42e90c1adc80040a08"), "name" : "joe", "emails" : [ "joe@gmail.com", "joe@yahoo.com", "joe@itpub.com", "joe@163.com", "joe@python.com" ]}

  有时我们需要基于特定条件来删除元素,而不仅仅依据位置,就可以使用$pull修改器

10. 数组修改器 $pull

  $pull修改器和$pop修改类似,都是用来删除数组中的元素

  $pull可以基于特定条件来删除元素
  $pull会将所有匹配到的数据全部删掉,如对数组[1,2,1,1]执行pull 1,得到的结果就是只有一个元素的数组[2]

  例如我们想删除emails数组中的"joe@163.com"和"joe@itpub.com"两个元素:

> db.users.findOne(){        "_id" : ObjectId("5770ca42e90c1adc80040a08"),        "name" : "joe",        "emails" : [                "joe@gmail.com",                "joe@yahoo.com",                "joe@itpub.com",                "joe@163.com",                "joe@python.com"        ]}> db.users.update({
"name":"joe"},{$pull:{
"emails":["joe@163.com","joe@itpub.com"]}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 }) --好像不能一次删除多个,没有起作用> db.users.findOne(){ "_id" : ObjectId("5770ca42e90c1adc80040a08"), "name" : "joe", "emails" : [ "joe@gmail.com", "joe@yahoo.com", "joe@itpub.com", "joe@163.com", "joe@python.com" ]}> db.users.update({
"name":"joe"},{$pull:{
"emails":"joe@163.com"}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.users.update({
"name":"joe"},{$pull:{
"emails":"joe@itpub.com"}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.users.findOne(){ "_id" : ObjectId("5770ca42e90c1adc80040a08"), "name" : "joe", "emails" : [ "joe@gmail.com", "joe@yahoo.com", "joe@python.com" ]}

11. 数组的定位修改器 $

  若是数组有多个值,而我们只想对其中一部分进行操作,有两种方法可以实现这种操作。

  两种方法操作数组中的值:通过位置或定位操作符("$")

  数组都是以0开头的,可以将下标直接作为键来选择元素。

> db.blog.findOne(){        "_id" : ObjectId("57709da84f533aa7535d46d3"),        "title" : "a blog post",        "comments" : [                {                        "name" : "joe",                        "email" : "joe@example.com",                        "content" : "nice post"                },                {                        "name" : "bob",                        "email" : "bob@example.com",                        "content" : "good post"                }        ]}> db.blog.update({
"title":"a blog post"},{$set:{
"comments.1.name":"livan"}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.blog.findOne(){ "_id" : ObjectId("57709da84f533aa7535d46d3"), "title" : "a blog post", "comments" : [ { "name" : "joe", "email" : "joe@example.com", "content" : "nice post" }, { "name" : "livan", "email" : "bob@example.com", "content" : "good post" } ]}> db.blog.update({
"title":"a blog post"},{$set:{
"comments.1.email":"livan@example.com"}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.blog.findOne(){ "_id" : ObjectId("57709da84f533aa7535d46d3"), "title" : "a blog post", "comments" : [ { "name" : "joe", "email" : "joe@example.com", "content" : "nice post" }, { "name" : "livan", "email" : "livan@example.com", "content" : "good post" } ]}

  在很多情况下,不预先查询文档就不能知道要修改数组的下标,为了克服这种困难,mongodb提供了定位操作符"$",

  用来定位查询文档已经匹配的元素,并进行更新,定位符只更新第一个匹配的元素。
  例如:用户john把名字改成了jim,就可以用定位符来替换评论中的名字:
  db.blog.update({"comments.author":"john"},{$set:{"comments.$.author:"john"}})
  可以理解为{"comments.author":"john"}查询条件定位到第一个元素,就执行{$set:      {"comments.$.author:"john"}},"$"定位符就表示找到的第一个元素

> db.blog.findOne(){        "_id" : ObjectId("57709da84f533aa7535d46d3"),        "title" : "a blog post",        "comments" : [                {                        "name" : "joe",                        "email" : "joe@example.com",                        "content" : "nice post"                },                {                        "name" : "livan",                        "email" : "livan@example.com",                        "content" : "good post"                }        ]}> db.blog.update({
"comments.name":"livan"},{$set:{
"comments.$.email":"bob@example.com"}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.blog.update({
"comments.name":"livan"},{$set:{
"comments.$.name":"bob"}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.blog.findOne(){ "_id" : ObjectId("57709da84f533aa7535d46d3"), "title" : "a blog post", "comments" : [ { "name" : "joe", "email" : "joe@example.com", "content" : "nice post" }, { "name" : "bob", "email" : "bob@example.com", "content" : "good post" } ]}

 

转载于:https://www.cnblogs.com/dong-/p/10176768.html

你可能感兴趣的文章
SecureCRT的使用方法和技巧(详细使用教程)
查看>>
右侧导航栏(动态添加数据到list)
查看>>
81、iOS本地推送与远程推送详解
查看>>
C#基础_注释和VS常用快捷键(一)
查看>>
虚拟DOM
查看>>
uva 11468 Substring
查看>>
自建数据源(RSO2)、及数据源增强
查看>>
BootStrap2学习日记2--将固定布局换成响应式布局
查看>>
关于View控件中的Context选择
查看>>
2018icpc徐州OnlineA Hard to prepare
查看>>
R语言-rnorm函数
查看>>
Spark的启动进程详解
查看>>
Java 字符终端上获取输入三种方式
查看>>
javascript 简单工厂
查看>>
java调用oracle存储过程,返回结果集
查看>>
使用命令创建数据库和表
查看>>
数据库的高级查询
查看>>
HttpClient(一)-- HelloWorld
查看>>
dump调试函数
查看>>
Android 利用Sharp样式设置文本框EditText圆角形状
查看>>