MongoDB(bin目录下)

连接MongoDB(bin目录下)
./mongo
如果觉得shell里空空的可以输入help,在刷屏的同时大致了解下有哪些方法
help
现在咱们还没有数据库,咱们创建一个,任性起名:template
use template
咱们确认下,数据库有没有创建成功
show dbs
template 0.078GB
如果存在template,就进入,如果没有,在最后保存的时候就会创建template
###insert###
发现已经创建成功,继续走,现在咱们创建一个集合,任性起名:room,再插入点数据
db.room.insert({“desk”:1,“bed”:1,“window”:2})
db.room.find()
{ “_id” : ObjectId(“55081e42591555a6c35dd695”), “desk” : 1, “bed” : 1, “window” : 2 }
####知识点####
insert会给文档增加一个id(如果原来没有的话),这个id是文档的唯一标示,然后保存到数据库中

###remove###
现在咱们不想要这个room文档了,那么来删除它
db.room.remove({})
注意,在remove() 里传入了空对象{},意为删除全部数据,除了这样删除,我们还可以这样删除
db.room.remove({“desk”:1})
####Tips####
db.dropDatabase()
删除数据库
db.collection.drop()
删除集合
###update###
update方法很强大,它有两个参数,一是查询文档,用来找出需要更新的文档,另一个是修改器(modifier)文档,描述对找到的文档做哪些修改。
####亮点#### 更新操作是原子的,若两个更新同时发生,先到达服务器的现执行,接着执行另一个。所以,互相冲突的更新可以火速传递,并不会互相干扰,虽然这是一个拼速度的年代,但是后更新的会取得“胜利”(后发制人!)
因为使用原子的 更新修改器 进行更新操作极为高效,所以,就决定用它了!
###KaTeX parse error: Expected 'EOF', got '#' at position 4: inc#̲## 例如:你需要存储一个网…inc来原子的增加(减少)count的值
db.web.update({“url”:“www.example”},{$inc:{“count”:1}})
{ “_id” : ObjectId(“55082435591555a6c35dd697”), “url” : “www.example”, “count” : 3 }
KaTeX parse error: Expected 'EOF', got '#' at position 40: …对象,1指定步长(正增负减) #̲##set & KaTeX parse error: Expected 'EOF', got '#' at position 6: unset#̲## 用set指定一个键的值,如果不存在,就创建它。这对更新模式或者增加用户定义很有帮助。
db.user.insert({“name”:“qianjiahao”})
此用户现在只有姓名信息,现在需要给他添加email
db.user.update({“name”:“qianjiahao”},{“KaTeX parse error: Expected 'EOF', got '}' at position 37: …e@example.com"}}̲) { "_id" : Obj…set”:{“hobby”:[“swimming”,“running”,“reading”]}})
{ “_id” : ObjectId(“55082691591555a6c35dd698”), “name” : “qianjiahao”, “email” : "example@example.com", “hobby” : [ “swimming”, “running”, “reading” ] }
假如他现在又没有爱好了…
db.user.update({“name”:“qianjiahao”},{“KaTeX parse error: Expected 'EOF', got '}' at position 19: …et":{"hobby":1}}̲) { "_id" : Obj…push###
数组修改器,既然名字都这样叫了,那么这个修改器就只能对数组进行操作啦。
db.user.update({“name”:“qianjiahao”},{“KaTeX parse error: Expected 'EOF', got '}' at position 27: …by":"sleeping"}}̲) { "_id" : Obj…addToSet & KaTeX parse error: Expected 'EOF', got '#' at position 5: each#̲## 用addToSet更新可以避免重复,将它与KaTeX parse error: Expected '}', got 'EOF' at end of input: …qianjiahao"},{"addToSet”:{“hobby”:{“KaTeX parse error: Expected 'EOF', got '}' at position 37: …ing","dancing"]}̲}}) { "_id" : O…pop###
如果将数组看做队列,可以用KaTeX parse error: Expected '}', got 'EOF' at end of input: …删除第一个或者最后一个元素 {pop:{“key”:-1}},{KaTeX parse error: Expected 'EOF', got '}' at position 14: pop:{"key":1}}̲ ###pull###
它可以删除所匹配的值,如果[1,1,2,1] 执行pull 1 后,只剩下[2]
###定位修改器### 如果要操作数组中的值,可以用值在数组中的位置当做参数来删除
db.user.update({“name”:“qianjiahao”},{“KaTeX parse error: Expected 'EOF', got '}' at position 26: …by.0":"crying"}}̲) { "_id" : Obj…来代替位置。
db.user.update({“hobby”:“crying”},{”KaTeX parse error: Expected '}', got 'EOF' at end of input: set":{"hobby.”:“smiling”}})
{ “_id” : ObjectId(“55082691591555a6c35dd698”), “name” : “qianjiahao”, “email” : "example@example.com”, “hobby” : [ “smiling”, “running”, “reading”, “sleeping”, “singing”, “eating”, “dancing” ] }
####upsert##
upsert是一个选项,它是update的第三个参数,并不是一个方法。它是一种特殊的更新,要是没有文档符合匹配,那么它就会根据条件和更新文档为基础,创建新的文档,如有匹配,则正常更新。咱们之前见到的所有update操作,都是建立在有文档的基础之上的。upsert非常方便,不必预制集合,同一套代码既可以创建又可以更新。
超市需要修改商品的价格,比如将苹果的价格上调0.5元,但是店主不确定自己是否有购进苹果(偶尔会犯糊涂),那么他可以这样
db.supermarket.update({“name”:“apple”},{KaTeX parse error: Expected 'EOF', got '}' at position 18: …t:{"price":5.5}}̲,True) 如果MongoD…inc:{“x”:2}},false,true)
db.runCommand({getLastError:1})
{ “connectionId” : 199, “updatedExisting” : true, “n” : 1, “syncMillis” : 0, “writtenTo” : null, “err” : null, “ok” : 1 }
###安全VS性能### insert、remove、update这些操作都是瞬间的,他们不需要等待数据库响应,可以理解为子弹从枪膛里射出但不关心射没射中!并不是说这些操作是异步的,而是说后面的事你不用担心了,说白了,子弹射出去后怎么飞、怎么击中目标那都是子弹的事了,咱也管不了了。
这个特点是速度快,快通常挺好,但是万一遇到点什么岔子,小到踢断网线,中到停电淹水,大到火山爆发。借用周星驰电影里的一句话:“世事难预料”,可能有些情况还能接受,但是如果是安全性要求很高的应用场景,那就不能接受了。
所以,安全性要求高的解决方案是:执行完操作,立刻返回getLastError,如果出错,一般都会抛出一个可捕获的异常,好及时处理,如果成功了,会给出额外的信息作为反馈。
但这样一来,性能方面肯定就不如之前了,因为用户会额外等待数据库做出响应。
至于具体是对安全性要求高,还是对性能要求高,要视具体情况而定。
终于到了CRUD的大哥:find方法了。
####第一个参数#### MongoDB使用find来进行查询,查询呢,就是返回一个集合中文档的子集,子集合的范围从0个文档到整个集合。
find的第一个参数决定了要返回那些文档,其形式也就一个文档,说明了要执行的查询细节。
通常呢,大家看到的find查询基本都长这个样子
db.user.find({})
db.user.find({“name”:“qianjiahao”})
db.user.find({“name”:“qianjiahao”,“email”:“example@example.com”})
####第二个参数#### 但是,有的时候,我们并不希望将文档中的所有键/值对都返回,这时,我们可以在find方法的第二个参数上指明我们希望返回的信息。
db.user.find({},{“name”:1,“email”:1})
上面的语句意思是:我们只想得到name和email,其他的不关心。像这样指明返回信息的做法肯定是有好处的,它可以帮助我们节省传输的数据量,又能节省客户端解码文档的时间和内存消耗。 比如,现在有这两条数据
{ “_id” : ObjectId(“5509087e08fa61313b5a8230”), “name” : “william”, “email” : "example@example.com" }
{ “_id” : ObjectId(“5509088b08fa61313b5a8231”), “name” : “jack”, “email” : "example@example1.com" }
我们只想得到name,连 _id 都不想要,那么可以这样
db.user.find({},{“name”:1,"_id":0})
{ “name” : “william” }
{ “name” : “jack” }
####注意#### 数据库关心的查询文档的值,必须是常量(在你自己的代码里可以是正常的变量),换句话说,不可以引用文档中其他键的值!
###查询条件###
####$lt $lte $gt KaTeX parse error: Expected 'EOF', got '#' at position 4: gte#̲### 以上四个分别表示为:…gte":18,“KaTeX parse error: Expected 'EOF', got '}' at position 8: lte":25}̲}) 这样的范围查询对查询日期…gte”:start}})
####注意#### 不要去匹配精确的日期,而是用范围来对日期进行查询
####$ne#### KaTeX parse error: Expected '}', got 'EOF' at end of input: …find({"name":{"ne":“william”}})
###OR查询### ####$in####
KaTeX parse error: Expected '}', got 'EOF' at end of input: …ind({"hobby":{"in":[“dancing”,“swimming”]}},{"_id":0})
{ “hobby” : “swimming”, “gender” : “female” }
{ “hobby” : “dancing”, “gender” : “male” } 若只查询会跳舞的人
db.user.find({“hobby”:{“KaTeX parse error: Expected 'EOF', got '}' at position 16: in":["dancing"]}̲},{"_id":0}) { …in,那么与之相对的就KaTeX parse error: Expected 'EOF', got '#' at position 21: …以查询到不包括指明信息的文档 #̲##or####
我们再添加一个游泳的人,并用KaTeX parse error: Expected '}', got 'EOF' at end of input: …ind({"hobby":{"in”:[“swimming”]}},{"_id":0})
{ “hobby” : “swimming”, “gender” : “female” }
{ “hobby” : “swimming”, “gender” : “male” }
i n 是 对 单 个 键 进 行 的 查 询 , 用 in 是对单个键进行的查询,用 inor查询可以匹配多个键
db.user.find({“KaTeX parse error: Expected 'EOF', got '}' at position 47: …der":"female"}]}̲,{"_id":0}) { "…or”:[{“hobby”:“swimming”},{“gender”:“male”}]},{"_id":0})
{ “hobby” : “swimming”, “gender” : “female” }
{ “hobby” : “dancing”, “gender” : “male” }
{ “hobby” : “singing”, “gender” : “male” }
{ “hobby” : “singing”, “gender” : “male” }
{ “hobby” : “dancing”, “gender” : “male” }
{ “hobby” : “swimming”, “gender” : “male” }
现在我们可以得出结论,OR查询($in 和 KaTeX parse error: Expected 'EOF', got '#' at position 48: …中一条及以上,即可被查询到。 #̲###not####
not 是元条件句,可以用于任何条件之上,意为取反
####注意#### 一个键不能对应多个更新修改器 但是可以对应多个条件查询句 比如,可以这样
db.user.find({“age”:{“ g t " : 18 , " gt":18," gt":18,"lt”:30}})
但是,不可以这样
{“ i n c " : " a g e " : 1 , " inc":{"age":1}," inc":"age":1,"set”:{“age”:20}}
因为他们修改了两次age
###查询数组###
####KaTeX parse error: Expected 'EOF', got '#' at position 4: all#̲### 利用all来查询所以…all:[“apple”,“cherry”]}},{"_id":0})
{ “fruit” : [ “apple”, “banana”, “cherry” ] }
与之前的OR查询($or i n ) 相 比 , in)相比, inall的查询模式更像是去取交集,即同时满足查询条件才能被查询出来。
####KaTeX parse error: Expected 'EOF', got '#' at position 5: size#̲### size可以获得指定数…size":3}},{"_id":0})
{ “fruit” : [ “apple”, “banana”, “cherry” ] }
{ “fruit” : [ “apple”, “banana”, “pear” ] }
{ “fruit” : [ “apple”, “watermelon”, “pear” ] }
###游标### 数据库使用游标来控制find的执行结果。
客户端对游标的实现通常能够对最终结果进行有效控制。
可以限制结果的数量,略过部分结果,对任意方向任意键的组合对结果进行排序,或者去执行一些功能强大的操作。
我们来看一例
var cursor = db.foo.find().sort({“x”:1}).limit(3).skip(5)
上面代码的意思是:对foo集合查询文档,参照x键的值升序排序,仅显示跳过前五个后的前三个文档。
在接触过Jquery后,感觉这样的链式函数调用很眼熟。
其实他们的原理是一样的,因为几乎所有的游标对象的方法都会返回游标本身,
所以才可以使用如此优雅的方式去调用函数。
####注意#### 在调用find的时候,shell并不立即查询数据库,
而是等待正要获得结果的时候才发送查询,这样在执行之前可以给查询附加额外的选项。
####limit、sort和skip####
limit指的是上限
sort里 1 为升序,-1为降序,如果sort里有多个值,那就按照多个键的顺序,依次排序
skip…就是skip(额)
用这三个方法可以通常可以用来制作分页。
####辩证的看待游标#### 在服务器端,游标消耗内存和其他资源。
游标遍历尽了结果以后,或者客户端发来消息要求终止,数据库将会释放这些资源,释放掉的资源可以被数据库换作他用。
这非常有必要,所以尽量保证尽快释放资源(在合理的前提下)
还有一些情况导致游标终止
首先,当游标完成了匹配结果的迭代时,它会清除自身。
另外,当游标在客户端已不在作用域内时,驱动会向服务器发送专门的消息,让其销毁。
最后,即便用户没有迭代完所有的结果,并且游标还在作用域内,10分钟不使用,数据库游标也会自动销毁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值