上篇讲了MongoDB的基础知识,大家应该对MongoDB有所了解了,当然真正用的还是curd操作,本篇为大家讲解MongoDB的curd操作。
1、数据库操作
#1、增 use config #如果数据库不存在,则创建数据库,否则切换到指定数据库。 #2、查 show dbs #查看所有 要想显示出刚创建的数据库,我们需要向数据库插入一些数据。 db.table1.insert({'a':1}) #3、删 use config #先切换到要删的库下 db.dropDatabase() #删除当前库
2、集合操作
#1、增 当第一个文档插入时,集合就会被创建 > use database1 switched to db database1 > db.table1.insert({'a':1}) WriteResult({ "nInserted" : 1 }) > db.table2.insert({'b':2}) WriteResult({ "nInserted" : 1 }) #2、查 > show tables table1 table2 #3、删 > db.table1.drop() true > show tables table2
3、文档操作
1)增加数据
#创建一个user的局部变量,这是一个JavaScript对象 user={ "name":"ming", 'is_nb':true, 'hobbies':['music','read','game'] } db.userinfo.insert(user) db.userinfo.find() user1={ "name":"asb", 'is_sb':true, 'hobbies':['music','sports'] } user2={ "name":"egon", 'is_sb':'wxx', 'hobbies':['music','read','dancing'] } user3={ "name":"alex", 'is_sb':false, 'hobbies':['music','read','girls'] } db.userinfo.insertMany([user1,user2,user3]) #一次插入多个文档
2)修改数据
1 复制代码 2 update() 方法用于更新已存在的文档。语法格式如下: 3 db.collection.update( 4 <query>, 5 <update>, 6 { 7 upsert: <boolean>, 8 multi: <boolean>, 9 writeConcern: <document> 10 } 11 ) 12 参数说明:对比update db1.t1 set name='EGON',sex='Male' where name='egon' and age=18; 13 14 query : 相当于where条件。 15 update : update的对象和一些更新的操作符(如$,$inc...等,相当于set后面的 16 upsert : 可选,默认为false,代表如果不存在update的记录不更新也不插入,设置为true代表插入。 17 multi : 可选,默认为false,代表只更新找到的第一条记录,设为true,代表更新找到的全部记录。 18 writeConcern :可选,抛出异常的级别。 19 20 更新操作是不可分割的:若两个更新同时发送,先到达服务器的先执行,然后执行另外一个,不会破坏文档。 21 22 update用法介绍
#1、最简单的更新就是用一个新的文档完全替换匹配的文档。这适用于大规模式迁移的情况。例如对下面的用户文档做 一个比较大的调整 > db.user.find().pretty() { "_id" : ObjectId("5a5b3a74c126b4b2cbb57e3f"), "name" : "ming", "girl_friends" : 20, "height" : 170 } # 先找到要修改的对象 > var obj=db.user.findOne({'name':'ming'}) > obj { "_id" : ObjectId("5a5b3a74c126b4b2cbb57e3f"), "name" : "ming", "girl_friends" : 20, "height" : 170 } # 修改 > obj.detail={'girl_friends':20,'height':170} { "girl_friends" : 20, "height" : 170} > obj.username=obj.name egon # 删掉不要的 > delete obj.girl_friends true > delete obj.height true > delete obj.name true # 完成更新 > db.user.update({'name':'ming'},obj) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.user.find() { "_id" : ObjectId("5a5b3a74c126b4b2cbb57e3f"), "detail" : { "girl_friends" : 20, "height" : 170}, "username" : "ming" } 简单更新
2、一个常见的错误 db.user.insert({'name':'ming','age':10}) db.user.insert({'name':'ming','age':20}) db.user.insert({'name':'ming','age':30}) > db.user.find() { "_id" : ObjectId("5a5b3ecac126b4b2cbb57e43"), "name" : "ming", "age" : 10 } { "_id" : ObjectId("5a5b3ecbc126b4b2cbb57e44"), "name" : "ming", "age" : 20 } { "_id" : ObjectId("5a5b3ecdc126b4b2cbb57e45"), "name" : "ming", "age" : 30 } # 找到的是第二个ming,他要过生日,于是长了一岁 > var obj=db.user.findOne({'name':'ming','age':20}) > obj.age++ # 我们的条件只定位到第二条记录这一条记录,所以更新是没问题的, > db.user.update({'name':'ming','age':20},obj) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) # 我们的条件定位到了多条记录,而obj对象的_id是一定的,文档中的_id是唯一的,我们无法将三条改成同一个_id,所以报错 > db.user.update({'name':'ming'},obj) #报错 # 删掉后,更新成功,但默认改的是第一条 > delete obj._id true > obj { "name" : "ming", "age" : 21 } > db.user.update({'name':'ming'},obj) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.user.find() { "_id" : ObjectId("5a5b40f6c126b4b2cbb57e46"), "name" : "ming", "age" : 21 } { "_id" : ObjectId("5a5b40f6c126b4b2cbb57e47"), "name" : "ming", "age" : 20 } { "_id" : ObjectId("5a5b40f6c126b4b2cbb57e48"), "name" : "ming", "age" : 30 } > # 所以针对这种情况,我们还以_id作为条件保证只定位到我们想要修改的对象,并且比起随机字符串,_id的查找速度更快 > db.user.update({'_id':ObjectId("5a5b40f6c126b4b2cbb57e47")},obj) # ps: 改多条 > db.user.update({'name':'ming'},obj,{'multi':true}) WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0, "writeError" : { "code" : 9, "errmsg" : "multi update only works with $ operators" #只能用修改器 } }) > db.user.update({'name':'ming'},{$set:obj},{'multi':true}) WriteResult({ "nMatched" : 3, "nUpserted" : 0, "nModified" : 1 }) 一个常见的错误
1 通常文档只会有一部分需要更新。可以使用原子性的更新修改器,指定对文档中的某些字段进行更新。 2 更新修改器是种特殊的键,用来指定复杂的更新操作,比如修改、增加后者删除 3 4 #=======>1、"$set"修改器 5 > db.user.find() 6 { "_id" : ObjectId("5a5b51a257147a04b81f2bb4"), "name" : "egon", "age" : 10 } 7 { "_id" : ObjectId("5a5b51a257147a04b81f2bb5"), "name" : "egon", "age" : 20 } 8 { "_id" : ObjectId("5a5b51a357147a04b81f2bb6"), "name" : "egon", "age" : 30 } 9 #完全覆盖原文档 10 > db.user.update({'_id':ObjectId("5a5b51a257147a04b81f2bb4")},{'age':111}) 11 WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) 12 > db.user.find() 13 { "_id" : ObjectId("5a5b51a257147a04b81f2bb4"), "age" : 111 } 14 { "_id" : ObjectId("5a5b51a257147a04b81f2bb5"), "name" : "egon", "age" : 20 } 15 { "_id" : ObjectId("5a5b51a357147a04b81f2bb6"), "name" : "egon", "age" : 30 } 16 > 17 18 #$set只更新原文档的一部分 19 > db.user.update({'_id':ObjectId("5a5b51a257147a04b81f2bb5")},{'$set':{'age':222}}) 20 WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) 21 > db.user.find() 22 { "_id" : ObjectId("5a5b51a257147a04b81f2bb4"), "age" : 111 } 23 { "_id" : ObjectId("5a5b51a257147a04b81f2bb5"), "name" : "egon", "age" : 222 } 24 { "_id" : ObjectId("5a5b51a357147a04b81f2bb6"), "name" : "egon", "age" : 30 } 25 26 # 有则更新,无则新增 27 > db.user.update({'age':30},{'$set':{'addr':{'country':'China','city':'BJ'}}}) 28 WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) 29 > db.user.find() 30 { "_id" : ObjectId("5a5b51a257147a04b81f2bb4"), "age" : 111 } 31 { "_id" : ObjectId("5a5b51a257147a04b81f2bb5"), "name" : "egon", "age" : 222 } 32 { "_id" : ObjectId("5a5b51a357147a04b81f2bb6"), "name" : "egon", "age" : 30, "addr" : { "country" : "China", "city" : "BJ" } } 33 34 35 # 修改内嵌文档 36 db.user.update({'age':30},{'$set':{'addr.country':'CHINA'}}) 37 38 # $unset 删除该键值对 39 db.user.update({'age':30},{'$unset':{'addr':'什么值都行'}}) 40 41 42 43 #=======>2、增加和减少 44 "$inc"修改器用来增加已经有的键的值(负数则为减少),或者该键不存在那就创建一个。只能用于整型、长整型或双浮点 45 的值。 46 对于更新分析数据、因果关系、投票或者其他有变化数值的地方,使用这个都会非法方便 47 48 49 例如: 50 > db.analytics.find() 51 { "_id" : ObjectId("5a5b4cb2126d610970c553ab"), "url" : "http://www.baidu.com", "pv" : 2 } 52 > db.analytics.update({'url':'http://www.baidu.com'},{'$inc':{'pv':1}}) 53 WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) 54 > db.analytics.find() 55 { "_id" : ObjectId("5a5b4cb2126d610970c553ab"), "url" : "http://www.baidu.com", "pv" : 3 } 56 使用修改器时,_id的值不能改变。其他的键值,包括其他的唯一索引的键,都是可以更改的。 57 注意:整个文档替换时可以改变_id 58 59 60 61 #=======>3、往数组内添加元素 62 如果数组已经存在,"$push"会向已有的数组末尾加入一个元素,要是没有就创建一个新的数组。 63 例如提交博客的评论 64 65 db.blog.insert({'_id':1,'name':'alex意外死亡的真相'}) 66 67 db.blog.update({'_id':1},{'$push':{'comments':{"name":"egon","content":'alex是谁???'}}}) 68 db.blog.update({'_id':1},{'$push':{'comments':{"name":"wxx","content":'我去,真的假的'}}}) 69 db.blog.update({'_id':1},{'$push':{'comments':{"name":"yxx","content":'吃喝嫖赌抽,欠下两个亿'}}}) 70 71 > db.blog.find().pretty() 72 { 73 "_id" : 1, 74 "name" : "alex意外死亡的真相", 75 "comments" : [ 76 { 77 "name" : "egon", 78 "content" : "alex是谁???" 79 }, 80 { 81 "name" : "wxx", 82 "content" : "我去,真的假的" 83 }, 84 { 85 "name" : "yxx", 86 "content" : "吃喝嫖赌抽,欠下两个亿" 87 } 88 ] 89 } 90 91 # 一次加多个"$push" 92 db.blog.update({'_id':1},{'$push':{'comments':{'$each':[{'name':'oldboy','content':'鼓掌'},{'name':'oldgirl','content':'一鞠躬'}]}}}) 93 94 > db.blog.find().pretty() 95 { 96 "_id" : 1, 97 "name" : "alex意外死亡的真相", 98 "comments" : [ 99 { 100 "name" : "egon", 101 "content" : "alex是谁???" 102 }, 103 { 104 "name" : "wxx", 105 "content" : "我去,真的假的" 106 }, 107 { 108 "name" : "yxx", 109 "content" : "吃喝嫖赌抽,欠下两个亿" 110 }, 111 { 112 "name" : "oldboy", 113 "content" : "鼓掌" 114 }, 115 { 116 "name" : "oldgirl", 117 "content" : "一鞠躬" 118 } 119 ] 120 } 121 122 123 # 限制大小"$slice",只留最后n个 124 db.blog.update({'_id':1},{'$push':{'comments':{'$each':[ 125 {'name':'xxx','content':'二鞠躬'}, 126 {'name':'yyy','content':'三鞠躬'}, 127 {'name':'yyy','content':'四鞠躬'}, 128 {'name':'zzz','content':'五鞠躬'}, 129 {'name':'mmm','content':'六鞠躬'}, 130 {'name':'nnn','content':'七鞠躬'}, 131 ], 132 '$slice':-7 133 }}}) 134 135 > db.blog.find().pretty() 136 { 137 "_id" : 1, 138 "name" : "alex意外死亡的真相", 139 "comments" : [ 140 { 141 "name" : "oldgirl", 142 "content" : "一鞠躬" 143 }, 144 { 145 "name" : "xxx", 146 "content" : "二鞠躬" 147 }, 148 { 149 "name" : "yyy", 150 "content" : "三鞠躬" 151 }, 152 { 153 "name" : "yyy", 154 "content" : "四鞠躬" 155 }, 156 { 157 "name" : "zzz", 158 "content" : "五鞠躬" 159 }, 160 { 161 "name" : "mmm", 162 "content" : "六鞠躬" 163 }, 164 { 165 "name" : "nnn", 166 "content" : "七鞠躬" 167 } 168 ] 169 } 170 171 172 173 174 #=======>4、The $sort element value must be either 1 or -1" 175 # '$sort':{'name': 1}升序排 176 db.blog.update({'_id':1},{'$push':{'comments':{'$each':[ 177 {'name':'aaa','content':'礼毕'}, 178 ], 179 '$slice':-3, 180 '$sort':{'name': 1} 181 }}}) 182 183 > db.blog.find().pretty() 184 { 185 "_id" : 1, 186 "name" : "alex意外死亡的真相", 187 "comments" : [ 188 { 189 "name" : "yyy", 190 "content" : "三鞠躬" 191 }, 192 { 193 "name" : "yyy", 194 "content" : "四鞠躬" 195 }, 196 { 197 "name" : "zzz", 198 "content" : "五鞠躬" 199 } 200 ] 201 } 202 203 # '$sort':{'name': -1} 降序排 204 db.blog.update({'_id':1},{'$push':{'comments':{'$each':[ 205 {'name':'aaa','content':'礼毕'}, 206 ], 207 '$slice':-2, 208 '$sort':{'name': -1} 209 }}}) 210 211 > db.blog.find().pretty() 212 { 213 "_id" : 1, 214 "name" : "alex意外死亡的真相", 215 "comments" : [ 216 { 217 "name" : "yyy", 218 "content" : "四鞠躬" 219 }, 220 { 221 "name" : "aaa", 222 "content" : "礼毕" 223 } 224 ] 225 } 226 227 228 #注意:不能只将"$slice"或者"$sort"与"$push"配合使用,且必须使用"$each" 229 230 231 232 #=======>5、避免添加重复 "$addToSet" 233 > db.urls.insert({'_id':1,'urls':[]}) 234 WriteResult({ "nInserted" : 1 }) 235 > db.urls.find() 236 { "_id" : 1, "urls" : [ ] } 237 238 db.urls.update({'_id':1},{'$addToSet':{'urls':'http://www.baidu.com'}}) 239 db.urls.update({'_id':1},{'$addToSet':{'urls':'http://www.baidu.com'}}) 240 db.urls.update({'_id':1},{'$addToSet':{'urls':'http://www.baidu.com'}}) 241 db.urls.update({'_id':1},{'$addToSet':{'urls':'http://www.python.org'}}) 242 > db.urls.find() 243 { "_id" : 1, "urls" : [ "http://www.baidu.com", "http://www.python.org" ] } 244 245 246 db.urls.update({'_id':1},{ 247 '$addToSet':{ 248 'urls':{ 249 '$each':['http://www.baidu.com','http://www.baidu.com','http://www.xxx.com'] 250 } 251 } 252 }) 253 > db.urls.find() 254 { "_id" : 1, "urls" : [ "http://www.baidu.com", "http://www.python.org", "http://www.xxx.com" ] } 255 256 257 #=======>6、删除元素 258 如果把数组看成是队列或者栈,可以用"$pop",这个修改器可以从数组任何一端删除元素。 259 {"$pop":{"key":1}} 从数组末尾删除一个元素 260 {"$pop":{"key":-1}} 从头部删除 261 262 263 > db.queue.insert({'_id':1,'queue':[]}) 264 WriteResult({ "nInserted" : 1 }) 265 # 入队列 266 db.queue.update({'_id':1},{'$push':{'queue':'alex'}}) 267 db.queue.update({'_id':1},{'$push':{'queue':'egon'}}) 268 db.queue.update({'_id':1},{'$push':{'queue':'wxx'}}) 269 db.queue.update({'_id':1},{'$push':{'queue':'yxx'}}) 270 271 > db.queue.find() 272 { "_id" : 1, "queue" : [ "alex", "egon", "wxx", "yxx" ] } 273 274 # 出队列 275 db.queue.update({'_id':1},{"$pop":{"queue":-1}}) 276 db.queue.update({'_id':1},{"$pop":{"queue":-1}}) 277 db.queue.update({'_id':1},{"$pop":{"queue":-1}}) 278 279 280 # "$pull" 把符合条件的统统删掉,而$pop只能按照位置删除 281 db.queue.update({'_id':1},{"$pull":{"queue":'yxx'}}) 282 283 284 285 286 #=======>7、基于位置的数组修改器 287 db.blog.insert({'_id':1,'name':'alex意外死亡的真相'}) 288 289 db.blog.update({'_id':1},{'$push':{'comments':{"name":"egon","content":'alex是谁???','thumb':20}}}) 290 db.blog.update({'_id':1},{'$push':{'comments':{"name":"wxx","content":'我去,真的假的','thumb':30}}}) 291 db.blog.update({'_id':1},{'$push':{'comments':{"name":"yxx","content":'吃喝嫖赌抽,欠下两个亿','thumb':40}}}) 292 293 > db.blog.find().pretty() 294 { 295 "_id" : 1, 296 "name" : "alex意外死亡的真相", 297 "comments" : [ 298 { 299 "name" : "egon", 300 "content" : "alex是谁???", 301 "thumb" : 20 302 }, 303 { 304 "name" : "wxx", 305 "content" : "我去,真的假的", 306 "thumb" : 30 307 }, 308 { 309 "name" : "yxx", 310 "content" : "吃喝嫖赌抽,欠下两个亿", 311 "thumb" : 40 312 } 313 ] 314 } 315 316 根据下标修改 317 db.blog.update({'_id':1},{'$set':{'comments.0.thumb':200}}) 318 319 320 必须查询才知道下表,所以提供了$,$ 代表根据条件匹配出的元素 321 db.blog.update({'comments.name':'wxx'},{'$set':{'comments.$.thumb':300}}) 322 323 324 325 #=======>8、upsert与multi 326 db.col.update( { "count" : { $gt : 5 } } , { $set : { "test5" : "OK"} },true,true ) #全部添加加进去 327 328 修改器
3)查数据
1 # 查找一条 2 db.userinfo.findOne() 3 # 查找所有 4 db.userinfo.find() 5 db.userinfo.find().pretty() #格式化显示 6 7 # 多个and条件 8 db.user.find({'name':'egon','age':{'$gt':20}}) 9 10 # 也可不写条件,代表匹配所有 11 db.user.find({}) 12 13 # 规定显示结果中有哪些key没有哪些key 14 > db.user.find({},{'_id':0,'name':1,'age':1}) 15 { "name" : "egon", "age" : 10 } 16 { "name" : "egon", "age" : 20 } 17 { "name" : "egon", "age" : 30 } 18 19 # "$lt" "lte" "$gt" "gte" "$ne",其中"$ne"能用于所有数据类型 20 db.user.find({'age':{'$gte':10,'$lt':30}}) 21 22 # or查询,or的条件放到[]内,注意:一个{}内逗号分开的多个条件相当于and 23 db.user.find({'$or':[{'name':'egon'},{'age':{'$gte':30}}]}) 24 25 # in和nin 26 db.user.find({'age':{'$in':[10,11,12,20]}}) 27 db.user.find({'age':{'$nin':[10,11,12,20]}}) 28 29 # {'$mod':[2,1]},对2取余如果为1则匹配成功 30 db.user.insert({'_id':1,'name':'egon','age':10}) 31 db.user.insert({'_id':2,'name':'egon','age':20}) 32 db.user.insert({'_id':3,'name':'egon','age':30}) 33 34 > db.user.find() 35 { "_id" : 1, "name" : "egon", "age" : 10 } 36 { "_id" : 2, "name" : "egon", "age" : 20 } 37 { "_id" : 3, "name" : "egon", "age" : 30 } 38 39 > db.user.find({'_id':{'$mod':[2,1]}}) 40 { "_id" : 1, "name" : "egon", "age" : 10 } 41 { "_id" : 3, "name" : "egon", "age" : 30 } 42 43 # not 取反 44 > db.user.find({'_id':{'$not':{'$mod':[2,1]}}}) 45 { "_id" : 2, "name" : "egon", "age" : 20 } 46 47 # {'key':null} 匹配key的值为null或者没有这个key 48 49 # 正则表达式 50 > db.user.find({'name':/^e.*?n$/i}) 51 { "_id" : 1, "name" : "egon", "age" : 10 } 52 { "_id" : 2, "name" : "egon", "age" : 20 } 53 { "_id" : 3, "name" : "egon", "age" : 30 } 54 55 # 查询数组 56 > db.food.insert({'fruit':['apple','banana','peach']}) 57 WriteResult({ "nInserted" : 1 }) 58 > db.food.find({'fruit':'banana'}) #只要存在就可以 59 { "_id" : ObjectId("5a5b7ad057147a04b81f2bc3"), "fruit" : [ "apple", "banana", "peach" ] } 60 61 > db.food.find({'fruit':{'$all':['banana','apple']}}) #既有banana又有apple 62 63 > db.food.find({'fruit.1':'banana'}) #按照位置 64 65 > db.blog.find().pretty() 66 { 67 "_id" : 1, 68 "name" : "alex意外死亡的真相", 69 "comments" : [ 70 { 71 "name" : "egon", 72 "content" : "alex是谁???", 73 "thumb" : 200 74 }, 75 { 76 "name" : "wxx", 77 "content" : "我去,真的假的", 78 "thumb" : 300 79 }, 80 { 81 "name" : "yxx", 82 "content" : "吃喝嫖赌抽,欠下两个亿", 83 "thumb" : 40 84 }, 85 { 86 "name" : "egon", 87 "content" : "xxx", 88 "thumb" : 0 89 } 90 ] 91 } 92 db.blog.find({},{'comments':{"$slice":-2}}).pretty() #查询最后两个 93 db.blog.find({},{'comments':{"$slice":[1,2]}}).pretty() #查询1到2 94 95 96 97 # 数组和范围查询的相互作用 98 db.test.insert({'x':5}) 99 db.test.insert({'x':15}) 100 db.test.insert({'x':25}) 101 db.test.insert({'x':[5,25]}) 102 103 > db.test.find({'x':{'$gt':10,'$lt':20}}) 104 { "_id" : ObjectId("5a5b8310b9b1b7388a40f993"), "x" : 15 } 105 { "_id" : ObjectId("5a5b8310b9b1b7388a40f995"), "x" : [ 5, 25 ] } 106 #发现连非数组的也找出来了,如果只想匹配数组,则用$elemMatch 107 > db.test.find({'x':{"$elemMatch":{'$gt':10,'$lt':20}}}) #匹配不到内容 108 > db.test.find({'x':{"$elemMatch":{'$gt':5,'$lt':115}}}) #25属于该范围 109 { "_id" : ObjectId("5a5b8310b9b1b7388a40f995"), "x" : [ 5, 25 ] } 110 111 #如果只想匹配非数组需要建立索引,结合min与max使用
4)删除数据
1 db.userinfo.deleteOne({ 'is_sb': true }) #删除多个中的第一个 2 db.userinfo.find() 3 db.userinfo.deleteMany( { 'x'': 1 } ) # 删除x=1的全部 4 db.userinfo.deleteMany({}) #删除全部
本篇讲解了MongoDB的增删改查语法,下篇讲解Springboot集成MongoDB操作。