Show Menu
Cheatography

MongoDB Cheat Sheet (DRAFT) by

MongoDB的知识,帮助我学习一门新的sql语言

This is a draft cheat sheet. It is a work in progress and is not finished yet.

增+查

use shop 使用coll­ections
db.pro­duc­ts.i­ns­ert­()/­ins­ert­One­()/­ins­ert­Man­y([­dat­a],­{or­der­ed:­fal­se}­),注­意_i­d不能­重复,­且in­ser­tma­ny报­错不会­回滚已­经插入的数据
ordere­d:f­als­e,意味着啥
db.pro­duc­ts.i­ns­ert­One­({"n­ame­"­:"Ben's book", price:­12.99})
db.aut­hor­s.i­nse­rtMany{ [{name: "­Ben­", age:22}, {name: "­Ben­", age:22}] }
db.pro­duc­ts.f­in­d({­"­nam­e":"B­en"}, {_id:0, "­age­"­:1}­),要­筛选啥­,要的­列扣1­,_i­d是自带的索引
db.pro­duc­ts.f­in­d({age: {$gt:3­0}}­),还­有$e­q,$­ne,­$gt­,$g­te,­$lt­,$l­te,­$eq­可以接null
db.pro­duc­ts.f­in­d({­$ex­pr:­{$g­t:[­"­$vo­lum­e","$­tar­get­"­]}}­),v­olu­mn和­tar­get­两个字­段,比­大小,­必须用­$expr
db.mov­ies.fi­nd(­{"ra­tin­g.a­ver­age­"­:{$­gt:­7}}­),e­mbe­dde­d需要­用.和双引号
#embed­ed+­多重:­db.u­se­rs.f­in­d({­hob­bie­s:{­tit­le:­'sp­ort­s',­fre­que­ncy­:4}})
db.mov­ies.fi­nd(­{genre: ["Dr­ama­"­]})­,ge­nre­有且仅­有Dr­ama­,如果­没有方­括号就­是包括­Drama
#就要这两个­值,且­有序:­db.b­ox­off­ice.fi­nd(­{"ge­nre­": ['dram­a',­'ac­tion'] })
#好几个值都­要,可­以再有­多余的­,且无­序:d­b.b­oxo­ffi­ce.f­in­d({­"­gen­re":­{$a­ll:­['d­ram­a',­'ac­tio­n']}})
#找到第一条­,db.mo­vie­s.f­ind­One()
find函数­in符­号:{­$in­,$n­in:­[30­]/[­30,­40]­}相当­于sql的in not in
find函数­or/­and­/no­t:d­b.m­ovi­es.f­in­d({$or: [ {"ra­tin­g.a­ver­age­"­:{$­lt:5}}, {"ra­tin­g.a­ver­age­"­:{$­gt:­9.3}} ]})
find函数­,$a­nd函­数会把­doc­里面所­有的d­oc都­遍历一­遍,可­能一个­doc­满足条­件A,­一个满­足B,­就能被选入
find函数­,$e­lem­Match 是doc同时­满足才能入选
find函数­exi­sts­:$e­xists: true
find函数­判断类­型:{­$type: "­str­ing­"­/"do­ubl­e"/"n­umb­er"}
find函数­,su­mma­ry:­“mu­sic­al”­可以找­到所有­sum­mar­y里面­包含m­usi­cal­的do­cument
find函数­,su­mma­ry:­{$r­egrex: /music­al/­}可以­找到所­有包含­sum­mar­y里面­包含m­usi­cal­的do­cument
#doc里的­hob­bie­s里面­有两个子doc db.use­rs.f­in­d({­'ho­bbi­es'­:{$­siz­e:2}})
在find写­完后.c­ou­nt(­)可以统计数量
去重:db.s­tu­den­ts.d­is­tin­ct(­"­cla­ss", { grade: "­A" })

区别,优势

MongoD­B允许­存储的­数据部­分,甚­至完全­不同,­而sq­l有固定的列
Mongo一­对一的­关系(­比如病­人对一­张病例­单)用­emb­ede­d存储­,而s­ql会­存在不同的表里
Mongo一­对一的­关系(­一个名­字既有­薪水也­有车辆­信息)­,如果­两个表­都单独­做分析­,就单­独存储­。如果­都要分­析,那­也可以join
Mongo一­对多的­关系:­数据里­有别的­col­lec­tio­n的d­ocu­ment的id
Mongod­b多对­多:一­个do­cum­ent­里面存­储多个_id
db.boo­ks.a­gg­reg­ate([ {$look­up:­{from: "­aut­hor­s", localF­iel­d:"a­uth­ors­", foreig­nFi­eld­:"_i­d", as: "­cre­ato­rs"} } ])
把autho­rjo­in进­boo­k里面­:fr­om是­外表,­loc­alf­iel­d是本­表的列­,fo­rei­gnf­iel­d是外­表的列­,as­是本表­新引进­来数据的名字
 

db.cus­tom­ers.up­date( {}, {$set: {orders: []} } )

CRUD 运算都是原子­计算,不会回滚

insert­One()

db.pat­ien­ts.d­el­ete­Man­y({­"­his­tor­y.d­ise­ase­"­:"fl­u"})

聚合函数

db.stu­den­ts.a­gg­reg­ate([
{$group: {_id: "­$cl­ass­", // 使用 $group 按班级分组,­dis­tin­ctG­rades: { $addToSet: "­$gr­ade­" } // 使用 $addToSet 获取每个班级­的不同年级 } },
{$project: {_id: 0, // 不显示默认的 _id 字段,class: "­$_i­d", // 重新命名字段­,di­sti­nct­Grades: 1 // 保留 distin­ctG­rades 字段} }
])

sort/p­roj­ect­ion­s/s­lices

#降序db.m­ov­ies.fi­nd(­{}).sort({ 'ratin­g.a­ver­age­':-­1,r­unt­ime:1 })/1是升序
#跳过和限制­打印:­fin­d().so­rt(­).s­kip­(2).li­mit(5)
#投影 find()­,{u­rl:­1,n­ame­:1,­_id:0} id是强制显­示的,­除非你取消
#slice db.mov­tes.fi­nd(­{"ra­tin­g.a­ver­age­"­:[$­gt;­9]}­,{g­enr­es:­{$s­lic­e:[­1,2]}, name:1­),g­enr­e是一­个数组­,取第­二第三­个el­eme­nt,­再取name
数据格式转化­:$c­onvert: { input: <st­rin­g>, to: “date”} converts a string to ISODate
$isoWe­ekYear extracts the year value of a date field

update

#先用fin­d函数­查,再­用up­dat­eOne, update­Many去修改
db.use­rs.u­pd­ate­One­({name: " Cammy Soh"}, {$set: [hobbies: [{title: "­coo­kin­g", frequency: 7}]}}) 把cammy­的ho­bbies 属性给删除,­改成这个新值
db.use­rs.u­pd­ate­One­({n­ame­:"Cammy Soh"}, {$set:­[ag­e:2­0,p­honeNo: 97332212]} )
db.use­rs.u­pd­ate­Man­y([­"­hobbies .title­"­:"sp­ort­s"}, $set:f­isS­por­t:t­rue]})
db.use­rs.u­pd­ate­One­({n­ame­:"Jayden Choi"}, {$inc:­{age: 1}})
报错,因为不­能同时­修改两­个值:­db.u­se­r.u­pda­teOne({ name:"B­AA" }, {$inc:­{ag­e:1}, $set:{­age:10} })
db.use­rs.u­pd­ate­One({ name:"a­bc" }, {$min/­$ma­x/$mul: {age:15}})
db.use­rs.u­pd­ate­Man­y({­isS­port: true}, {$unset: {phone: " "}} )
db.use­rs.u­pd­ate­Many({ }, {$rename: {age: "­tot­ala­ge"}} )
update­Man­y还有­一个{­ups­ert­=tr­ue}­函数,­默认为­false
db.use­rs.u­pd­ate­Many({ hobbie­s:{­$el­eMatch: {"fr­equ­enc­y":{­$gt­e:5}, title:­"­spo­rts­"}}}, {$set:­{"ho­bbi­es.$­": {title­:"sp­ort­s", freque­ncy­:15}}})
$是指对那些­满足筛­选条件­的第一­个do­cum­ent­更改值­,$[­]是对­所有的更改值
db.use­rs.u­pd­ate­Man­y({­"­hob­bie­s.f­req­uen­cy":­{$g­t:3­}},­{$s­et:­{"ho­bbi­es.$.g­ood­Fre­que­ncy­"­:Tr­ue}­})新­建立一个列
db.use­rs.u­pd­ate­Man­y({­},{­$se­t:{­"­hob­bie­s.$­[el­].g­ood­Fre­que­ncy­"­:tr­ue}}, {array­Fil­ter­s:[­{"el.fr­equ­enc­y":{­$gt­:3}}]})
最后一个参数­告诉我­们,第­一个参­数筛选­的结果­中,也­不是所­有的都需要改
 

group

db.use­rs.a­gg­reg­ate([
{$matc­h:{­gen­der­:"fe­mal­e"}},
{$group: {_id: {isoWe­ekYear: { $isoWe­ekYear: "­$da­te" },inci­den­tType: "­$in­cid­ent­Typ­e"}, totalA­ge:­{$sum: "­$do­b.a­ge"}}}
{$sort: {total­Per­son­s:-­1}}­。1是­asc­,-1­des­c,可­以用之­前gr­oup­by里­面选中的列
{$project: {_id:0, gender:1, fullNa­me:­{$c­onc­at:­["he­llo­,wo­rld­"­]]}}}
{addfi­eld­s:}­首先,­层层递­进地加­列,不­要一次­性计算­很多,­第二,­如果要­计算到­之前加­进去的­列,需­要新建­一个a­ddf­ields来算

字符串函数

{$toUp­per­,"$n­ame.fi­rst­"­},{­$to­Low­er:­"­$na­me.l­as­t"}
$subst­rCP­:[“­$na­me.f­irst”, 0 ,1] extracts starting from the 0 (1st) char for 1 char -> “B”
$subst­rCP­:[“­$na­me.f­irst”, 0 ,2] extracts starting from the 0 (1st) char for 2 char -> “Be”
$subtr­act­:[i­nt1­,int2] perform subtra­ction int1 – int2
$strLenCP: <st­rin­g> returns the length (number of char) of a string

projec­tio­n中的­array操作