您的位置:首页 > 数据库 > Mongodb

[置顶] MongoDB3.2增删查改方法简述(CRUD操作)

2016-12-26 21:56 477 查看
一、前序
无论什么数据库,都必须会有增删查改的操作,只是方法形式不一样而已,其实思路还是差不多的,
下面我们就对MongoDB3.2版本的文档操作简述并验证一下

二、查select:

简单查询:
>db.t1.find()
{ "_id" : ObjectId("585ce007d993c80e8713c7bd"), "x" : 1, "j" : 1 }
{ "_id" : ObjectId("585ce007d993c80e8713c7be"), "x" : 4, "j" : 2 }
{ "_id" : ObjectId("585ce007d993c80e8713c7bf"), "x" : 2, "j" : 3 }
{ "_id" : ObjectId("585ce008d993c80e8713c7c0"), "x" : 4, "j" : 4 }
{ "_id" : ObjectId("585ce023d993c80e8713c7c2"), "x" : 3 }
排序查询:
>db.t1.find().sort({j:-1})     ---"1"表示升序,“-1”表示降序
{ "_id" : ObjectId("585ce008d993c80e8713c7c0"), "x" : 4, "j" : 4 }
{ "_id" : ObjectId("585ce007d993c80e8713c7bf"), "x" : 2, "j" : 3 }
{ "_id" : ObjectId("585ce007d993c80e8713c7be"), "x" : 4, "j" : 2 }
{ "_id" : ObjectId("585ce007d993c80e8713c7bd"), "x" : 1, "j" : 1 }
{ "_id" : ObjectId("585ce023d993c80e8713c7c2"), "x" : 3 }
比较查询:
>db.t1.find({j:{$gt:2,$lte:4}})          ---查询j字段大于2,小于等于4的记录
{ "_id" : ObjectId("585ce007d993c80e8713c7bf"), "x" : 2, "j" : 3 }
{ "_id" : ObjectId("585ce008d993c80e8713c7c0"), "x" : 4, "j" : 4 }
$gt:大于
$lt:小于
$gte:大于等于
$lte:小于等于

根据条件只显示某一字段值
> db.t1.find({x:1},{j:true})          ---查询x=1的记录,且只显示j字段值
{ "_id" : ObjectId("585ce007d993c80e8713c7bd"), "j" : 1 }
{ "_id" : ObjectId("585ce007d993c80e8713c7be"), "j" : 2 }
{ "_id" : ObjectId("585ce007d993c80e8713c7bf"), "j" : 3 }
如需消去_id字段显示,可:
> db.t1.find({x:1},{j:true,_id:false})
{ "j" : 1 }
{ "j" : 2 }
{ "j" : 3 }
多个值in查询(类似IN)
> db.t1.find({j:{$in:[1,4]}})          ---j=1或j=4的记录
{ "_id" : ObjectId("585ce007d993c80e8713c7bd"), "x" : 1, "j" : 1 }
{ "_id" : ObjectId("585ce008d993c80e8713c7c0"), "x" : 4, "j" : 4 }
多个值and查询(类似AND)
> db.t1.find({x:1,j:{$gt:1}})          ---x=1 and j>1条件记录
{ "_id" : ObjectId("585ce007d993c80e8713c7be"), "x" : 1, "j" : 2 }
{ "_id" : ObjectId("585ce007d993c80e8713c7bf"), "x" : 1, "j" : 3 }
多个值or查询(类似OR)
> db.t1.find({$or:[{x:4},{j:{$lte:2}}]})     ---x=4 or j<=2的条件记录
{ "_id" : ObjectId("585ce007d993c80e8713c7bd"), "x" : 1, "j" : 1 }
{ "_id" : ObjectId("585ce007d993c80e8713c7be"), "x" : 1, "j" : 2 }
{ "_id" : ObjectId("585ce008d993c80e8713c7c0"), "x" : 4, "j" : 4 }
多个值or  and 查询

> db.t1.find({x:1,$or:[{j:{$lt:2}},{j:3}]})     ---x=1 and (j<2 or j=3)
{ "_id" : ObjectId("585ce007d993c80e8713c7bd"), "x" : 1, "j" : 1 }
{ "_id" : ObjectId("585ce007d993c80e8713c7bf"), "x" : 1, "j" : 3 }


查询表中不包括 j 字段的记录
>db.t6.find({j:{$exists:false}})          ---查询包含j字段的话,就是$exists:true
{ "_id" : ObjectId("585ce023d993c80e8713c7c2"), "x" : 3 }

查询子文档中存在某个字段的记录
可以使用点来连接
>db.getCollection('t6').find({"kk.city":{$exists:true}})     ---查询kk子文档中存在有city字段的数据
根据子文档中某几个字段的值进行匹配查询:
>db.t6.find({kk:{deviceID:222,city:"Tianjin"}})          ---查询kk子文档中deviceID=222且city:"Tianjin"的记录
{ "_id" : 1, "x" : 2, "kk" : { "deviceID" : 222, "city" : "Tianjin" } }
或
> db.t6.find({"kk.deviceID":222,"kk.city":"Tianjin"})     ---与上一个方法一样的效果,注意双引号的使用
只返回子文档中的某些字段
> db.t6.find({},{"kk.deviceID":1,_id:0})
{ "kk" : { "deviceID" : 222 } }
{ "kk" : { "deviceID" : 222 } }
{  }
{  }
只返回数组中的第几个元素值
> db.t6.find({x:3},{_id:0,x:0,pp:{$slice:-1}})     ---查询x=3的记录,且只返回数组pp的最后一个元素值,使用$slice
{ "pp" : [ "p3" ] }




三、 插入insert


普通插入
>db.t2.insert({x:5,j:6})
数组插入
>db.t2.insert([{_id:11,item:"pencil",qty:50,type:"no2"},     ---以数组的形式插入多个document
... {item:"pen",qty:20},
... {item:"eraer",qty:25}]
... )
单一插入
>db.t2.insertOne({item:"card",qty:15},{a:22,b:33})          ---只会插入第一个document
多文档插入

> db.t2.insertMany([{item:"p",qty:1},{item:"e",qty:2},{item:"n",qty:3}])

四、更新UPDATE

更新其实也有很多种方法:
db.collection.updateOne()     ---3.2版本的新功能,只更新匹配查询条件的第一个document记录
db.collection.updateMany()     ---3.2版本的新功能,更新匹配查询条件的所有document记录,其余功能和update()基本一致
db.collection.update()
db.collection.replaceOne()          ---3.2版本的新功能,只更新替换匹配查询条件的第一个document记录,并且是替换整个

先单独试验一下各自常用功能,后续再详述上述方法之不同
4.1 update()

update默认情况下,只更新一条记录

     语法格式:
db.collection.update(
<query>,     ---以{}形式填写查询条件,与find()方法一样
<update>,     ---更新动作,常用的是$set,以设置字段的新值
{
upsert: <boolean>,     ---可选,当query的document不存在时,直接insert一个文档
multi: <boolean>,     ---update()默认最多只更新一条记录,multi:true可以多文档更新
writeConcern: <document>     ---一个完成返回模式,详细可查看官方文档
})
实例collection:
>db.t3.find()
{
_id: 100,
sku: "Johnny",
quantity: 250,
instock: true,
reorder: false,
details: { model: "14Q2", make: "xyz" },
tags: [ "apparel", "clothing" ],
ratings: [ { by: "ijk", rating: 4 } ]
}
{
_id: 101,
sku: "Johnny",
quantity: 251,
instock: true,
reorder: false,
details: { model: "22Q2", make: "abc" },
tags: [  "clothing" ],
ratings: [ { by: "ijk", rating: 4 } ]
}

使用$set
>db.t3.update(
{ _id: 100 },
{ $set:
{
quantity: 500,
details: { model: "14Q3", make: "xyz" },
tags: [ "red", "outerwear", "clothing" ]
}
}
)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })     ---返回值,提示只更新了一条记录,事实确实也是只更新了一条
>db.t3.find()
{
_id: 100,
sku: "Johnny",
quantity: 500,
instock: true,
reorder: false,
details: { model: "14Q3", make: "xyz" },
tags: [ "apparel", "clothing","red" ],
ratings: [ { by: "ijk", rating: 4 } ]
}
{
_id: 101,
sku: "Johnny",
quantity: 251,
instock: true,
reorder: false,
details: { model: "22Q2", make: "abc" },
tags: [  "clothing" ],
ratings: [ { by: "ijk", rating: 4 } ]
}
--使用$set操作更新了三种类型,quantity数值,details嵌入式文档型,tags数组型


upsert的使用即在update时,如果查询不到相应document,则会直接在集合中insert入一条新document记录
>db.t1.find()
{ "_id" : ObjectId("585ce007d993c80e8713c7bd"), "x" : 1, "j" : 1 }
> db.t1.update({x:5},{$set:{j:5}},{upsert:true})     ---因为查询不到x:5的记录,所以直接insert一条document记录
WriteResult({
"nMatched" : 0,
"nUpserted" : 1,
"nModified" : 0,
"_id" : ObjectId("5860c6acc2742b7e1500ca53")
})
> db.t1.find()
{ "_id" : ObjectId("585ce007d993c80e8713c7bd"), "x" : 1, "j" : 1 }
{ "_id" : ObjectId("5860c6acc2742b7e1500ca53"), "x" : 5, "j" : 5 }
更新整个document(注意是document,不是整个collection)
> db.t1.find()
{ "_id" : ObjectId("585ce007d993c80e8713c7bd"), "x" : 1, "j" : 1 }
{ "_id" : ObjectId("585ce023d993c80e8713c7c2"), "x" : 3 }
> db.t1.update({x:3},{x:3,j:6})
WriteResult({ "nMatched" : 1, "nUpse
c64a
rted" : 0, "nModified" :1 })
> db.t1.find()
{ "_id" : ObjectId("585ce007d993c80e8713c7bd"), "x" : 1, "j" : 1 }
{ "_id" : ObjectId("585ce023d993c80e8713c7c2"), "x" : 3, "j" : 6 }     ---直接更新了此document的内容
注:因在update这一部分没有加诸如$set之类的操作,仅以field:value的形式,则会直接更新整个document,这样可以用来添加或删除字段
添加新字段   
> db.t1.update(
... {x:5},
... {$set:{y:5}},
... {multi:true}     ---此参数可更新多个document,可选项
... )
> db.t1.find()
{ "_id" : ObjectId("5860c6acc2742b7e1500ca53"), "x" : 5, "j" : 5, "y" : 5 }     ---之前document中没有“y”字段,

重命名字段名($rename)
>db.t2.update(
{_id:"12_1_001"},
{$rename:{"class_id":"clasID"}}          ---class_id是旧字段名,classID是新名字
)

删除某个字段
> db.t1.find()
{ "_id" : ObjectId("585ce007d993c80e8713c7bd"), "x" : 1, "j" : 1 }
{ "_id" : ObjectId("585ce023d993c80e8713c7c2"), "x" : 6, "j" : 6, "y" : 6}
> db.t1.update({x:6},{$unset:{y:5}})          ---y字段之后的值不重要,不写6,依然可以删除此字段
> db.t1.find()
{ "_id" : ObjectId("585ce007d993c80e8713c7bd"), "x" : 1, "j" : 1 }
{ "_id" : ObjectId("585ce023d993c80e8713c7c2"), "x" : 6, "j" : 6 }
db.collection.replaceOne()
是直接替换符合条件的整个document
语法格式:
db.collection.replaceOne(
<filter>,     ---查询条件
<replacement>,     ---待替换后的新document内容
{
upsert: <boolean>,
writeConcern: <document>,
collation: <document>
})
实例:
> db.t1.find()
{ "_id" : ObjectId("585ce023d993c80e8713c7c2"), "x" : 6, "j" : 6 }
> db.t1.replaceOne({x:6},{j:7})
{ "_id" : ObjectId("585ce023d993c80e8713c7c2"), "j" : 7 }     ---注意此处少了x:6,因为是直接更新替换了整个document


五、删除


官方提供的删除document的方法:
db.collection.remove()
db.collection.deleteOne()          ---3.2新功能,删除符合条件的第一个document
db.collection.deleteMany()          ---3.2新功能,删除符合条件的所有文档
对于大量的删除操作,把你想要保留的文档复制到一个新的集合然后使用
db.collection.drop() 方法删除原集合或许会更高效(官方建议)
用法最活跃的remove()
语法格式:
db.collection.remove(
<query>,
{
justOne: <boolean>,     ---true或false 表示只删除符合查询条件顺序的第一个document
writeConcern: <document>,
collation: <document>
})
注:删除集合的文档,不会删除索引(即使删除所有文档)

> db.t4.insert({a:1,b:2})
>db.t4.createIndex({a:1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
>db.t4.remove({})          ---传入空文档{},则表示删除集合中的所有文档
> db.t4.getIndexes()          ---此时查询索引,依然存在
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "tt.t4"
},
{
"v" : 1,
"key" : {
"a" : 1
},
"name" : "a_1",
"ns" : "tt.t4"
}
]
只删除符合条件的第一条document记录
> db.t4.find()
{ "_id" : ObjectId("5860dd2b22c84900e7e4c02c"), "a" : 1, "b" : 2 }
{ "_id" : ObjectId("5860dd2d22c84900e7e4c02d"), "a" : 1, "b" : 1 }
{ "_id" : ObjectId("5860dd3022c84900e7e4c02e"), "a" : 1, "b" : 3 }
> db.t4.deleteOne({a:1})
> db.t4.find()
{ "_id" : ObjectId("5860dd2d22c84900e7e4c02d"), "a" : 1, "b" : 1 }
{ "_id" : ObjectId("5860dd3022c84900e7e4c02e"), "a" : 1, "b" : 3 }
使用remove()
>db.t4.remove({a:1},true)     ---两种写法,也可以这样写:db.t4.remove({a:1},{justOne:true})
> db.t4.find()
{ "_id" : ObjectId("5860dd2d22c84900e7e4c02d"), "a" : 1, "b" : 1 }
{ "_id" : ObjectId("5860dd3022c84900e7e4c02e"), "a" : 1, "b" : 3 }
六、批量操作

上面讲了一堆增删改查的操作,不过都是单一英雄操作,如果我们想批量操作怎么办,那就拍一个《复仇者联盟》就好了呀----BulkWrite()
官方的介绍是:MongoDB提供给客户端可以批量执行写操作的能力,不过只能影响一个collection
BulkWrite()支持一下写操作:
insertOne
updateOne
updateMany
replaceOne
deleteOne
deleteMany
语法格式:
>db.collection.bulkWrite(
[ <operation 1>, <operation 2>, ... ],
{
writeConcern : <document>,
ordered : <boolean>
})
operation1、operation2都是一个个的修改操作,以文档的形式放在 [ ] 数组中
ordered:默认是true,即按照修改操作的顺序执行,如果过程中某一操作报错,则剩余的操作将中断
     false时,则是平行执行,一个操作的报错异常,不会影响到其余操作,但官方一般不建议,因为没有保证性
实验:

> db.t4.find()
> db.t4.bulkWrite([
... {insertOne:{"document":{_id:1,a:1,name:"James"}}},
... {insertOne:{"document":{_id:2,a:2,name:"Johnny"}}},
... {updateOne:{"filter":{a:1},"update":{$set:{name:"Jack"}}}},
... {deleteOne:{"filter":{a:2}}}])
{
"acknowledged" : true,
"deletedCount" : 1,
"insertedCount" : 2,
"matchedCount" : 1,
"upsertedCount" : 0,
"insertedIds" : {
"0" : 1,
"1" : 2
},
"upsertedIds" : {

}
}
> db.t4.find()
{ "_id" : 1, "a" : 1, "name" : "Jack" }


实验结果:
     插入一条、更新其中一条、删除其中一条
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: