MongoDB的CRUD

mongod是一个文本型数据库,存入数据库的都是一个一个文本。文本用{}括起来,并且文本中的内容都是键值对,和json格式差不多,但是在mongo中,它是一种和json格式很像的bson格式
比如{"a":1}就是一个文本,{"a":{"b":1,"c":2}}是复杂的嵌入性文本
1.insert
1)db.collection.insertOne()添加一个文本

db.collection.insertOne({"f":6})
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5a981304007156b408f7d902")
}

插入成功返回成功插入文本的_id
2)db.collection.insertMany()添加多个文本
按照自己的理解插入多条数据

db.collection.insertMany({"d":4},{"e":5})
2018-03-01T07:43:38.088-0700 E QUERY    [thread1] TypeError: documents.map is not a function :
DBCollection.prototype.insertMany@src/mongo/shell/crud_api.js:283:1

看了mongo shell methods的实例才发现方法参数是一个数组

db.collection.insertMany([{"d":4},{"e":5}])
{
    "acknowledged" : true,
    "insertedIds" : [
        ObjectId("5a9811c5007156b408f7d900"),
        ObjectId("5a9811c5007156b408f7d901")
    ]
}

成功插入以后会返回所有插入文本的_id
3)db.collection.insert()可以添加进一个,也可以添加进多个
eg

db.test_update.insert({"a":1})
WriteResult({ "nInserted" : 1 })

db.test_update.insert(db.collection.insert([{"c":3},{"g":7}])
BulkWriteResult({
    "writeErrors" : [ ],
    "writeConcernErrors" : [ ],
    "nInserted" : 2,
    "nUpserted" : 0,
    "nMatched" : 0,
    "nModified" : 0,
    "nRemoved" : 0,
    "upserted" : [ ]
})
)

会返回成功插入文本的数量
4)db.collection.save()

db.collection.save({item:"book", qty:40})
WriteResult({ "nInserted" : 1 })
db.collection.save({"_id":100,"item":"water","qty":30})
WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : 100 })

调用save插入数据的两种情况,一是不指定_id,相当于insert()方法,指定_id,相当于update with upsert。如果指定的_id在数据库中存在,则这条数据将会被更新,否则插入这条数据
此时插入的数据:

{ "_id" : ObjectId("5a98174a007156b408f7d907"), "item" : "book", "qty" : 40 }
{ "_id" : 100, "item" : "water", "qty" : 30 }

在执行一次指定_id的save()方法

db.collection.save({"_id":100,"item":"juice"})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

此时数据库中的数据:

{ "_id" : ObjectId("5a98174a007156b408f7d907"), "item" : "book", "qty" : 40 }
{ "_id" : 100, "item" : "juice" }

使用save插入多条数据

db.collection.save([{"x":1},{"y":2},{"z":3}])
BulkWriteResult({
    "writeErrors" : [ ],
    "writeConcernErrors" : [ ],
    "nInserted" : 3,
    "nUpserted" : 0,
    "nMatched" : 0,
    "nModified" : 0,
    "nRemoved" : 0,
    "upserted" : [ ]
})

insert()和save()的区别:
如果不指定_id,则insert()和save()之间没什么区别
如果指定了_id,并且这个_id在数据库中存在,则save()将更新数据库,但是insert()不会对数据库起任何改变

db.collection.find()
{ "_id" : 100, "item" : "water", "qty" : 30 }
db.collection.insert({"_id":100, "item":"test"})
WriteResult({
    "nInserted" : 0,
    "writeError" : {
        "code" : 11000,
        "errmsg" : "E11000 duplicate key error collection: admin.collection index: _id_ dup key: { : 100.0 }"
    }
})

插入数据将会报主键重复
对于insert方法,成功以后会返回两种信息:一是成功插入文本的条数,二是成功插入文本的objectId
2.delete
1)db.collection.deleteMany({})删除所有文本

db.collection.deleteMany({})
{ "acknowledged" : true, "deletedCount" : 4 }
db.collection.count()
0

删除成功以后会返回删除的条数
2)db.collection.deleteMany(new Document(),condition)删除所有满足条件的文本

db.collection.deleteMany({"a":1})
{ "acknowledged" : true, "deletedCount" : 2 }

删除所有含a:1的文本

db.collection.deleteMany({"a":{$gt:2}})
{ "acknowledged" : true, "deletedCount" : 2 }

删除含a>2的所有文本
在复杂一些,包含多个条件
数据库中的数据:

{ "_id" : ObjectId("5a98b9641435c363f9c0686f"), "a" : 1 }
{ "_id" : ObjectId("5a98b9641435c363f9c06870"), "a" : 2 }
{ "_id" : ObjectId("5a98b9641435c363f9c06871"), "a" : 3 }
{ "_id" : ObjectId("5a98b9641435c363f9c06872"), "a" : 4, "d" : 4 }
{ "_id" : ObjectId("5a98b9641435c363f9c06873"), "a" : 4, "d" : 5 }

删除a>2并且d=4的文档

db.collection.deleteMany({"a":{$gt:2},"d":4})
{ "acknowledged" : true, "deletedCount" : 1 }

删除语法可以大致总结为:db.collection.deleteMany({field1:condition},{field2:condition}...),对所有的delete方法都是适用的
3)db.collection.deleteOne(new Document(), condition)删除满足条件
的第一个文本

db.collection.deleteOne({"a":1})
{ "acknowledged" : true, "deletedCount" : 1 }

删除成功以后都会返回成功删除数据的条数
4)db.collection.remove()删除一个或多个满足条件的文本

db.collection.remove({})
WriteResult({ "nRemoved" : 17 })
test:PRIMARY> db.collection.count()
0

删除所有数据
condition:
3.update:
db.collection.updateMany()更新满足条件的所有文本
首先得在集合中插入足够多的数据,这里我们使用mongodb官方文档提供的数据:

db.inventory.insertMany( [
...    { item: "canvas", qty: 100, size: { h: 28, w: 35.5, uom: "cm" }, status: "A" },
...    { item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
...    { item: "mat", qty: 85, size: { h: 27.9, w: 35.5, uom: "cm" }, status: "A" },
...    { item: "mousepad", qty: 25, size: { h: 19, w: 22.85, uom: "cm" }, status: "P" },
...    { item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "P" },
...    { item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
...    { item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
...    { item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" },
...    { item: "sketchbook", qty: 80, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
...    { item: "sketch pad", qty: 95, size: { h: 22.85, w: 30.5, uom: "cm" }, status: "A" }
... ] );

在inventory集合中插入多条数据
updateMany()方法会更新所有符合条件的文本
eg:

db.inventory.updateMany(
    {"qty":{$lt:50}},
    {$set:{"size.uom":"in","status":"p"},
    $currentDate:{lastModified:true}}
)
{ "acknowledged" : true, "matchedCount" : 3, "modifiedCount" : 3 }

这条语句会更新所有qty<50的文本,对文本中的size.uom和status的内容进行修改
$currentDate会更新lastModified字段的值,如果这个字段不存在,则会创建这个字段
更新成功以后,会返回成功更改文本的数量
db.collection.updateOne()更新满足条件的第一个文本
db.collection.update()
$set对指定字段的值进行替换
数据库中的一条数据:

{ "_id" : ObjectId("5a9d255f824f61fbe944a70e"), "name" : "lele", "age" : 17 }

将"name":"lele"修改为"name":"lala"
eg:

db.test_collection.update({"name":"lele"},{$set:{"name":"lala"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

基本语法:

db.collection.update({field:value},{$set:{field:value1}})

db.collection.replaceOne()也可以起到update的效果
注:updateOne()、updateMany()、replaceOne()方法存在upsert字段,如果这个字段为true,那么如果没有一个文本匹配上过滤器,则会在database中插入一条新的数据
4.query
1)db.collection.find({})
这应该是最简单的查询语句了,查询出collection集合中的所有数据,等同于下面的sql语句

select * from table_name

2)db.collection.find({field:value})查询出指定条件的文本
eg:

 db.inventory.find({"item":"mat"})
{ "_id" : ObjectId("5aa4b63d4e8ef96bb530f94c"), "item" : "mat", "qty" : 85, "size" : { "h" : 27.9, "w" : 35.5, "uom" : "cm" }, "status" : "A" }

等同于下面的sql语句:

select * from table_name where field = value

3)db.collection.find({field:{operation:[value1,value2]}})
eg:

db.inventory.find({"status":{$in:["A","D"]}})

找到status为A或者D的文本
等同于下面的sql语句

select * from table_name where field in (value1, value2)

4)范围查找
还是直接上例子吧
example-a:specify and condition

db.inventory.find( { status:"A", "qty":{$lt:90}})

查找出status为A,qty<90的文本
等同于下面的sql语句:

select * from inventory where status = "A" and qty < 90

example-b:specify and condition

db.inventory.find({$or:[{"status":"A"},{"qty":{$lt:30}}]})

查找出status为A或者qty<30的文本
等同于下面的sql语句

select * from inventory where status = "A" or qty < 30

基本语法:
db.collection.find({$or:[{},{}]})
[]里面是可以或的条件

example-c:specify and as well as or condition

db.inventory.find({"status":"A",$or:[{"qty":{$lt:30}},{"item":/^p/}]})

查找出status为A,并且qty<30或者item是p开头的文本
等同于下面的sql语句

select * from inventory where status = "A" and (qty < 30 or item like "p%")

5)db.collection.findOne()
查找出集合中的第一个文本

db.inventory.findOne()
{
        "_id" : ObjectId("5aa4b63d4e8ef96bb530f94a"),
        "item" : "canvas",
        "qty" : 100,
        "size" : {
                "h" : 28,
                "w" : 35.5,
                "uom" : "cm"
        },
        "status" : "A"
}

等同于db.collection.find({}).limit(1)

 db.inventory.find({}).limit(1)
{ "_id" : ObjectId("5aa4b63d4e8ef96bb530f94a"), "item" : "canvas", "qty" : 100, "size" : { "h" : 28, "w" : 35.5, "uom" : "cm" }, "status" : "A" }

两者的区别大概就只有查询出的内容排版格式不一样吧
6)查询嵌入式文本
假设collection中有这样一条数据

{ "_id" : ObjectId("5aa4b63d4e8ef96bb530f952"), "item" : "sketchbook", "qty" : 80, "size" : { "h" : 14, "w" : 21, "uom" : "cm" }, "status" : "A" }

查询size为{ "h" : 14, "w" : 21, "uom" : "cm" }的文本

db.inventory.find({"size":{"h":14,"w":21,"uom":"cm"}})

h、w、uom的顺序必须和collection中的顺序一致
如下查询语句

db.inventory.find({"size":{"w":21,"h":14,"uom":"cm"}})

查询内容为空

查询size中uom为in的文本

db.inventory.find({"size.uom":"in"})

通过.访问复合文本中的具体字段
语法大致可以概括为:db.collection.find({field1.field2:value})或者是范围查询db.collection.find({field1.field2:condition})
eg:

db.inventory.find({"size.h":{$lt:15}})

condition可以是and、or、and和or的组合
7)查询数组
为了测试查询数组,我们在inventory中插入如下数据

db.inventory.insertMany([
   { item: "journal", qty: 25, tags: ["blank", "red"], dim_cm: [ 14, 21 ] },
   { item: "notebook", qty: 50, tags: ["red", "blank"], dim_cm: [ 14, 21 ] },
   { item: "paper", qty: 100, tags: ["red", "blank", "plain"], dim_cm: [ 14, 21 ] },
   { item: "planner", qty: 75, tags: ["blank", "red"], dim_cm: [ 22.85, 30 ] },
   { item: "postcard", qty: 45, tags: ["blue"], dim_cm: [ 10, 15.25 ] }
]);

example-a:match an array
eg:

db.inventory.find({"tags":["red","blank"]})

将查询出tag:[red,blank]的文本,可以看作是精确查找
注意到插入的数据中tags内容为tags: ["blank", "red"],tags: ["red", "blank"]的文本,查询时是根据顺序来的,如果不想根据顺序,想将只要tags中包含blank和red的文本查询出来,可以通过$all来忽略顺序
eg:

db.inventory.find({"tags":{$all:["red","blank"]}})
{ "_id" : ObjectId("5aa4d4a04e8ef96bb530f954"), "item" : "journal", "qty" : 25, "tags" : [ "blank", "red" ], "dim_cm" : [ 14, 21 ] }
{ "_id" : ObjectId("5aa4d4a04e8ef96bb530f955"), "item" : "notebook", "qty" : 50, "tags" : [ "red", "blank" ], "dim_cm" : [ 14, 21 ] }
{ "_id" : ObjectId("5aa4d4a04e8ef96bb530f956"), "item" : "paper", "qty" : 100, "tags" : [ "red", "blank", "plain" ], "dim_cm" : [ 14, 21 ] }
{ "_id" : ObjectId("5aa4d4a04e8ef96bb530f957"), "item" : "planner", "qty" : 75, "tags" : [ "blank", "red" ], "dim_cm" : [ 22.85, 30 ] }

example-b:query an array for an element
查询出只要数组中还有指定内容的文本
eg:

 db.inventory.find({"tags":"red"})

查询出inventory中tags数组含有red字段的文本
基本语法大概如下:
db.inventory.find({array_field:value})

example-c:query for an element by the array index position
查询数组时,可以通过下标去指定数组中第几个元素应该满足的条件
eg:

db.inventory.find({ "dim_cm.1": { $gt:25}})

这条语句将查询出dim_cm数组中第二个元素>=30的文本

example-d:query an array by array length
查询出满足指定数组长度的文本
eg:

db.inventory.find({"tags":{$size:3}})

查询出tags数组长度为3的文本

example-e:Query an Array with Compound Filter on the Array Elements
eg:

db.inventory.find({"dim_cm":{$gt:15,$lt:20}})
{ "_id" : ObjectId("5aa500a24e8ef96bb530f95e"), "item" : "journal", "qty" : 25, "tags" : [ "blank", "red" ], "dim_cm" : [ 14, 21 ] }
{ "_id" : ObjectId("5aa500a24e8ef96bb530f95f"), "item" : "notebook", "qty" : 50, "tags" : [ "red", "blank" ], "dim_cm" : [ 14, 21 ] }
{ "_id" : ObjectId("5aa500a24e8ef96bb530f960"), "item" : "paper", "qty" : 100, "tags" : [ "red", "blank", "plain" ], "dim_cm" : [ 14, 21 ] }
{ "_id" : ObjectId("5aa500a24e8ef96bb530f962"), "item" : "postcard", "qty" : 45, "tags" : [ "blue" ], "dim_cm" : [ 10, 15.25 ] }

只要数组中有一个元素15,或者有一个元素小于20,或者有一个元素大于15并且小于20,这个文本就会被查询出来

example-f:Query for an Element by the Array Index Position
eg:

db.inventory.find({"dim_cm":{$elemMatch:{$gt:15,$lt:20}}})
{ "_id" : ObjectId("5aa500a24e8ef96bb530f962"), "item" : "postcard", "qty" : 45, "tags" : [ "blue" ], "dim_cm" : [ 10, 15.25 ] }

只有数组中有一个大于15并且小于20的元素,这个文本就会被查询出来
example-e和example-f的唯一区别是数组中的元素是否需要同时满足两个条件

8)查询返回指定字段
example-a return the specified fields and the _id field only
eg:

db.inventory.find({"status":"A"},{"item":1,"status":1})

返回item、status和 _id字段
等同于下面的sql语句

select item, status, _id from inventory where status = "A"  

基本语法大致如下:

db.collection.find({field:value},{field1:1,field2:1})

example-b:suppress _id field
eg:

db.inventory.find({"status":"A"},{"item":-1,"status":1,_id:0})

通过指定_id:0将不会将_id字段返回回来
等同于下面的sql语句:

select item, status from inventory where status = "A"  

基本语法大致如下:

db.collection.find({field:value},{field:1, _id:0})

example-c:return all but the excluded fields
eg:

db.inventory.find({"status":"A"},{"status":0,"instock":0})

返回文本中的所有字段除了被指定为0的字段
基本语法大致如下:

db.collection.find({field:value},{field1:0,field2:0})

example-d:project specific array elements in the returned array
eg:

db.inventory.find({"status":"A"},{"item":1,"status":1,"instock":{$slice:-1}})

通过使用$slice,将会返回item、status、_id、instock数组最后一个元素的内容

9)查询null或者缺少的字段
插入数据:

db.inventory.insertMany([
   { _id: 1, item: null },
   { _id: 2 }
])

eg:

 db.inventory.find({"item":null})

将会查询出item为null或者不存在item字段的文本

eg:

db.inventory.find({"item":{$exists:false}})

返回不存在item字段的文本

eg:

 db.inventory.find({"item":{$type:10}})

返回item字段为null的文本
$type:10代表bson type中的null值
所以想要查询出某个字段为null的文本的正确语法为

db.collection.find({"field":{$type:10}})

而不是直接用null

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容

  • 数据库相关 显示所有的数据库:show dbs 切换数据库(若不存在,则直接创建):use test 删除数据库:...
    Eve0阅读 165评论 0 0
  • NoSql数据库优缺点 在优势方面主要体现在下面几点: 简单的扩展 快速的读写 低廉的成本 灵活的数据模型 在不足...
    dreamer_lk阅读 2,681评论 0 6
  • mongoDB是一个使用非常广的非关系型数据库,在springboot中,可以非常方便的实现CRUD操作。 1.p...
    冬天里的懒喵阅读 701评论 0 8
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,497评论 18 139
  • ﹤1﹥ 简字篇 花儿热烈 柳丝轻拂 月儿弯弯 河水盈盈 徜徉 春风和煦 音乐流淌 暗香涌动 轻轻驻足 醉享 ...
    相逢萍水阅读 285评论 0 2