欢迎来到李先生的博客

深山的鹿,不知归处;万般皆苦,只可自渡。
扩大
缩小

创建、更新和删除(三)

一:插入
插入是向MongoDB中添加数据的基本方法
 
db.test.insert()
    > use testdb
    switched to db testdb
    > db.test.insert({"name":"lile"})
    WriteResult({"nInserted":1})
    > db.test.findOne()
    {"_id":ObjectId("595f4e66f713ea7372854b9d"),"name":"lile"}

 

当想要一次性插入多个文档时,可以使用数组的形式db.test.insert([{},{},{}])
    > db.test.insert([{"name":"ha"},{"name":"he"},{"name":"hei"}])
    BulkWriteResult({
    "writeErrors":[],
    "writeConcernErrors":[],
    "nInserted":3,
    "nUpserted":0,
    "nMatched":0,
    "nModified":0,
    "nRemoved":0,
    "upserted":[]
    })

 

然后查询,可以看到刚刚插入的文档
    > db.test.find()
    {"_id":ObjectId("595f4e66f713ea7372854b9d"),"name":"lile"}
    {"_id":ObjectId("595f52fff713ea7372854b9e"),"name":"ha"}
    {"_id":ObjectId("595f52fff713ea7372854b9f"),"name":"he"}
    {"_id":ObjectId("595f52fff713ea7372854ba0"),"name":"hei"}

 

还有很多关于insert的操作,如insertOne()、insertMany()等,官网:
 
 
二、删除
db.test.remove() 将会删除test集合中的所有文档
db.test.remove({"_id":ObjectId("595f4e66f713ea7372854b9d")})   删除test集合中指定id号的文档
remove函数不会删除集合本身,也不会删除集合的元信息
 
若要删除集合,则使用drop函数,db.test.drop()把整个test集合给删掉,集合里的文档以及元数据都会删除,再用show tables查看时,不会再显示刚刚出现的集合
    > db.test.drop()
    true
    > show tables;
    >

 

三、更新文档
文档插入数据库以后,就可以使用update方法来更新,update有两个参数,一个是查询文档,用于定位需要更新的目标文档;另一个是修改器(modifier)文档,用于说明要对找到的文档进行哪些修改。
 
更新操作是不可分割的:若是两个更新同时发生,先到达服务器的先执行,接着执行另一个。
 
1)文档替换   用一个新的文档完全替换匹配的文档
先插入一条数据
    > db.user.insert({"name":"joe","friends":32,"enemies":2})
    WriteResult({"nInserted":1})

 

然后有了新的需求,需要把friends和enemies两个字段移到relationships中
    > var joe = db.user.findOne({"name":"joe"}) //这里一定要这样findOne才行,find不行
    > joe.relationship ={"friends":joe.friends,"enemies":joe.enemies};
    {"friends":32,"enemies":2}
    > delete joe.friends
    true
    > delete joe.enemies
    true
    > db.user.update({"_id":ObjectId("5962dde4530365edfecb4915")},joe)
    WriteResult({"nMatched":1,"nUpserted":0,"nModified":1})
    > db.user.findOne()
    {
    "_id":ObjectId("5962dde4530365edfecb4915"),
    "name":"joe",
    "relationship":{
    "friends":32,
    "enemies":2
    }
    }

 

2)使用修改器
通常文档只有一部分要更新。可以使用原子性的更改修改器(update modifier),指定对文档中的某些字段进行更新,更改修改器是种特殊的键,用来指定复杂的更新操作,比如修改、增加或者删除,还有可能是数组或者内嵌文档
 
例1:$inc
在一个集合中放置网站的分析数据,只要有人update,就使得页面的访问量加1,先在一个集合中插入文档
    > db.web.insert({"url":"www.lile.com",pageviews:23})
    WriteResult({"nInserted":1})
    > db.web.findOne()
    {
    "_id":ObjectId("5962e533530365edfecb4917"),
    "url":"www.lile.com",
    "pageviews":23
    }

 

每更新一次,pageviews就增加1
    > db.web.update({"url":"www.lile.com"},{"$inc":{pageviews:1}})
    WriteResult({"nMatched":1,"nUpserted":0,"nModified":1})

 

例2:$set
首先,插入一个文档
    > db.user.insert({"name":"joe","age":30,"sex":"male"})
    WriteResult({"nInserted":1})

 

再这个文档中,想要再添加喜欢的书籍进去:
    > db.user.update({"_id":ObjectId("5962eaf9530365edfecb4918")},{"$set":{"favorite book":"war and peace"}})
    WriteResult({"nMatched":1,"nUpserted":0,"nModified":1})

 


过了一段时间,发现喜欢的是另一本书
    > db.user.update({"_id":ObjectId("5962eaf9530365edfecb4918")},{"$set":{"favorite book":"Green hags and arm"}})
    WriteResult({"nMatched":1,"nUpserted":0,"nModified":1})
    > db.user.findOne()
    {
    "_id":ObjectId("5962eaf9530365edfecb4918"),
    "name":"joe",
    "age":30,
    "sex":"male",
    "favorite book":"Green hags and arm"
    }

 

也可以喜欢多本书,用数组表示
    > db.user.update({"_id":ObjectId("5962eaf9530365edfecb4918")},{"$set":{"favorite book":["war and peace","harbt"]}})
    WriteResult({"nMatched":1,"nUpserted":0,"nModified":1})
    > db.user.findOne()
    {
    "_id":ObjectId("5962eaf9530365edfecb4918"),
    "name":"joe",
    "age":30,
    "sex":"male",
    "favorite book":[
    "war and peace",
    "harbt"
    ]
    }

 

例3: $unset
有一天突然发现自己不喜欢书了,可以删掉
    > db.user.update({"_id":ObjectId("5962eaf9530365edfecb4918")},{"$unset":{"favorite book":1}})
    WriteResult({"nMatched":1,"nUpserted":0,"nModified":1})
    > db.user.findOne()
    {
    "_id":ObjectId("5962eaf9530365edfecb4918"),
    "name":"joe",
    "age":30,
    "sex":"male"
    }

 

$set 修改内嵌文档
首先,插入一个博客文档
    > db.blog.insert({"title":"A blog Post","Content":"hahaha....","author":{"name":"joe","email":"lile@qq.com"}})
    WriteResult({"nInserted":1})
    > db.blog.findOne()
    {
    "_id":ObjectId("5962edc8530365edfecb4919"),
    "title":"A blog Post",
    "Content":"hahaha....",
    "author":{
    "name":"joe",
    "email":"lile@qq.com"
    }
    }

 

名字弄错了,我想修改
    > db.blog.update({"_id":ObjectId("5962edc8530365edfecb4919")},{"$set":{"author.name":"joe schome"}})
    WriteResult({"nMatched":1,"nUpserted":0,"nModified":1})
    > db.blog.findOne()
    {
    "_id":ObjectId("5962edc8530365edfecb4919"),
    "title":"A blog Post",
    "Content":"hahaha....",
    "author":{
    "name":"joe schome",
    "email":"lile@qq.com"
    }
    }

 

例4:增加和减少  $inc 
$inc 修改器用来增加已有键的值,或者键不存在就创建一个,用于分析数据,因果关系,投票或其他有变化数值的地方
 
假若建立一个游戏集合,将游戏和变化的分数都存在里面,每过关一次,增加50分
    > db.game.insert({"game":"pinball","user":"joe"})
    WriteResult({"nInserted":1})
    > db.game.findOne()
    {
    "_id":ObjectId("5962ef3b530365edfecb491a"),
    "game":"pinball",
    "user":"joe"
    }
    > db.game.update({"_id":ObjectId("5962ef3b530365edfecb491a")},{"$inc":{"score":50}})
    WriteResult({"nMatched":1,"nUpserted":0,"nModified":1})
    > db.game.findOne()
    {
    "_id":ObjectId("5962ef3b530365edfecb491a"),
    "game":"pinball",
    "user":"joe",
    "score":50
    }
    > db.game.update({"_id":ObjectId("5962ef3b530365edfecb491a")},{"$inc":{"score":50}})
    WriteResult({"nMatched":1,"nUpserted":0,"nModified":1})
    > db.game.findOne()
    {
    "_id":ObjectId("5962ef3b530365edfecb491a"),
    "game":"pinball",
    "user":"joe",
    "score":100
    }

 

$inc只能用于整形,长整型或双精度浮点型的值
 
3):数组修改器 $push
在上面的博客系统中,要创建一个用于保存数组的comments评论键,$push会向已有的数组末尾加入一个元素,要是没有就创建一个新的数组。
    > db.blog.update({"_id":ObjectId("5962edc8530365edfecb4919")},{"$push":{"comments":{"name":"lile","email":"lile.qq.com","content":"nice post"}}})
    WriteResult({"nMatched":1,"nUpserted":0,"nModified":1})
    > db.blog.findOne()
    {
    "_id":ObjectId("5962edc8530365edfecb4919"),
    "title":"A blog Post",
    "Content":"hahaha....",
    "author":{
    "name":"joe schome",
    "email":"lile@qq.com"
    },
    "comments":[
    {
    "name":"lile",
    "email":"lile.qq.com",
    "content":"nice post"
    }
    ]
    }

 

若还想添加评论,可以继续使用$push,会在后面加一条评论数据
 
$ecah的用法,有一个个人的而基本信息,记录他的体重变化值
    > db.math.insert({"name":"lile"})
    WriteResult({"nInserted":1})
    > db.math.findOne()
    {"_id":ObjectId("5962f328530365edfecb491b"),"name":"lile"}

 

使用$push 和 $each可以一次性在数组中插入多个值,而不是一次只能插入一个数据
    > db.math.update({"_id":ObjectId("5962f328530365edfecb491b")},{"$push":{"weight":{"$each":[{"month":58},{"Feb":60},{"Jun":62}]}}})
    WriteResult({"nMatched":1,"nUpserted":0,"nModified":1})
    > db.math.findOne()
    {
    "_id":ObjectId("5962f328530365edfecb491b"),
    "name":"lile",
    "weight":[
    {
    "month":58
    },
    {
    "Feb":60
    },
    {
    "Jun":62
    }
    ]
    }

 

$slice 限制插入数组的个数,$slice的值为负数,表示若插入的个数没有超过这个数,那么全部写入,若超过了,那么就取后面的个数
    > db.math.update({"_id":ObjectId("5962f328530365edfecb491b")},{"$push":{"weight":{"$each":[23,45,6,6,67,45,24],"$slice":-3}}})
    WriteResult({"nMatched":1,"nUpserted":0,"nModified":1})
    > db.math.findOne()
    {
    "_id":ObjectId("5962f328530365edfecb491b"),
    "name":"lile",
    "weight":[
    67,
    45,
    24
    ]
    }

 


一个人的朋友信息,只允许写两个朋友,再写了多个的情况下,按年龄排序,取最后两个
    > db.math.findOne()
    {"_id":ObjectId("5962f328530365edfecb491b"),"name":"lile"}
    > db.math.update({"_id":ObjectId("5962f328530365edfecb491b")},{"$push":{"friends":{"$each":[{"name":"lile","age":12},{"name":"xiaoming","age":34},{"name":"small red","age":23}],"$slice":-2,"$sort":{"age":1}}}})
    WriteResult({"nMatched":1,"nUpserted":0,"nModified":1})
    > db.math.findOne()
    {
    "_id":ObjectId("5962f328530365edfecb491b"),
    "name":"lile",
    "friends":[
    {
    "name":"small red",
    "age":23
    },
    {
    "name":"xiaoming",
    "age":34
    }
    ]
    }

 

例6:$addToSet  
    > db.users.update({"_id":ObjectId("59631989530365edfecb491c")},{"$addToSet":{"emails":"lile4.qq.com"}})
    WriteResult({"nMatched":1,"nUpserted":0,"nModified":1})
    >
    >
    > db.users.findOne()
    {
    "_id":ObjectId("59631989530365edfecb491c"),
    "name":"joe",
    "emails":[
    "lile.qq.com",
    "lile2.qq.com",
    "lile3.qq.com",
    "lile4.qq.com"
    ]
    }


$addToSet和$each一起使用,插入数组多个值

    > db.users.update({"_id":ObjectId("59631989530365edfecb491c")},{"$addToSet":{"emails":{"$each":["lile5.qq.com","lile6.qq.com"]}}})
    WriteResult({"nMatched":1,"nUpserted":0,"nModified":1})
    > db.users.findOne()
    {
    "_id":ObjectId("59631989530365edfecb491c"),
    "name":"joe",
    "emails":[
    "lile.qq.com",
    "lile2.qq.com",
    "lile3.qq.com",
    "lile4.qq.com",
    "lile5.qq.com",
    "lile6.qq.com"
    ]
    }

 


 
删除元素
有几个从数组中删除元素的方法。如果是把数组看成队列或者栈,可以使用$pop
这个修改器从数组任何一端删除元素{"$pop":{"key":1}} 从数组末尾删除一个元素
{"$pop":{"key":-1}} 从数组头部删除一个元素
 
例1:删除emails的第一个元素
    > db.users.findOne()
    {
    "_id":ObjectId("59631989530365edfecb491c"),
    "name":"joe",
    "emails":[
    "lile.qq.com",
    "lile2.qq.com",
    "lile3.qq.com",
    "lile4.qq.com",
    "lile5.qq.com",
    "lile6.qq.com"
    ]
    }
    > db.users.update({"_id":ObjectId("59631989530365edfecb491c")},{"$pop":{"emails":-1}})
    WriteResult({"nMatched":1,"nUpserted":0,"nModified":1})
    > db.users.findOne()
    {
    "_id":ObjectId("59631989530365edfecb491c"),
    "name":"joe",
    "emails":[
    "lile2.qq.com",
    "lile3.qq.com",
    "lile4.qq.com",
    "lile5.qq.com",
    "lile6.qq.com"
    ]
    }

 

例2:数组中某个字段操作
 
原文是这样
    > db.blog.findOne()
    {
    "_id":ObjectId("5962edc8530365edfecb4919"),
    "title":"A blog Post",
    "Content":"hahaha....",
    "comments":[
    null,
    {
    "name":"lile",
    "email":"lile.qq.com",
    "content":"hahahhahahah post"
    },
    {
    "name":"small red",
    "email":"lile.qq.com",
    "content":"This is bad blog"
    }
    ]
    }

 

删除comments数组中的第一个数值null
    > db.blog.update({"comments.name":"lile"},{"$pop":{"comments":-1}})
    WriteResult({"nMatched":1,"nUpserted":0,"nModified":1})
    > db.blog.findOne()
    {
    "_id":ObjectId("5962edc8530365edfecb4919"),
    "title":"A blog Post",
    "Content":"hahaha....",
    "comments":[
    {
    "name":"lile",
    "email":"lile.qq.com",
    "content":"hahahhahahah post"
    },
    {
    "name":"lile",
    "email":"lile.qq.com",
    "content":"this is a bad blog"
    }
    ]
    }

 

然后我想在comments数组里,每一个值里添加一个字段votes,暂时只想到这种办法
    > db.blog.findOne()
    {
    "_id":ObjectId("5962edc8530365edfecb4919"),
    "title":"A blog Post",
    "Content":"hahaha....",
    "comments":[
    {
    "name":"lile",
    "email":"lile.qq.com",
    "content":"hahahhahahah post"
    },
    {
    "name":"lile",
    "email":"lile.qq.com",
    "content":"this is a good blog"
    }
    ]
    }
    > db.blog.update({"_id":ObjectId("5962edc8530365edfecb4919")},{"$set":{"comments.0.votes":0}})
    WriteResult({"nMatched":1,"nUpserted":0,"nModified":1})
    > db.blog.findOne()
    {
    "_id":ObjectId("5962edc8530365edfecb4919"),
    "title":"A blog Post",
    "Content":"hahaha....",
    "comments":[
    {
    "name":"lile",
    "email":"lile.qq.com",
    "content":"hahahhahahah post",
    "votes":0
    },
    {
    "name":"lile",
    "email":"lile.qq.com",
    "content":"this is a good blog"
    }
    ]
    }
    > db.blog.update({"_id":ObjectId("5962edc8530365edfecb4919")},{"$set":{"comments.1.votes":0}})
    WriteResult({"nMatched":1,"nUpserted":0,"nModified":1})
    > db.blog.findOne()
    {
    "_id":ObjectId("5962edc8530365edfecb4919"),
    "title":"A blog Post",
    "Content":"hahaha....",
    "comments":[
    {
    "name":"lile",
    "email":"lile.qq.com",
    "content":"hahahhahahah post",
    "votes":0
    },
    {
    "name":"lile",
    "email":"lile.qq.com",
    "content":"this is a good blog",
    "votes":0
    }
    ]
    }

 

删除刚刚添加的votes字段,只需把$set改为$unset即可
 
$用法,只会在第一个匹配的元素更新,而且做查询的时候必须是数组里的元素,不然会报错
 
这里是用_id号来匹配,报错
 
    > db.blog.update({"comments.name":"lile"},{"$set":{"comments.$.votes":0}})
    WriteResult({"nMatched":1,"nUpserted":0,"nModified":1})
    > db.blog.findOne()
    {
    "_id":ObjectId("5962edc8530365edfecb4919"),
    "title":"A blog Post",
    "Content":"hahaha....",
    "comments":[
    {
    "name":"lile",
    "email":"lile.qq.com",
    "content":"hahahhahahah post",
    "votes":0
    },
    {
    "name":"lile",
    "email":"lile.qq.com",
    "content":"this is a good blog"
    }
    ]
    }

posted on 2017-07-10 16:00  Captain_Li  阅读(728)  评论(0编辑  收藏  举报

导航