学习 mongo

痴心易碎 提交于 2019-12-31 21:19:07

mongo中集合是没有模式的表,文档是行,每一个文档中都有一个特殊的键"_id",在文档所处的集合中是唯一的。

一个文档中不能有重复的键,比如{"a":1,"a":2}是非法的。

其实可以将所有文档全部放在一个集合中,不过。。。想想就知道很恼火

mongo中多个文档组成集合,多个集合组成数据库,想要在同一个mongodb服务器上存放多个应用或者用户的数据,就要使用不同的数据库了。

创建,更新以及删除文档

1.插入文档

db.foo.insert({"bar":"baz"})

mongo_lib:insert(foo, #{<<"bar">> => baz})

如果要插入多个文档,批量插入好一些,因为只用单个的TCP请求,单个文档有插入的最大值,mongodb 1.8是16MB

2.删除文档

db.users.remove({a:1})

mongo_lib:delete(users, {a,1})

删除文档操作会将所有匹配的文档给删除,当时索引会保留

3.更新文档

db.user.update({a:2},{b:3})

mongo_lib:update(user, {a,2},#{b=>3})

3.1 使用修改器更新文档

$set 可以指定一个键的值,如果这个键不存在则创建它, 也可以用$unset删除某一个键,在只想更改某一个文档的某一个键时,就需要使用修改器,如果直接使用update会将整个文档替换掉

db.blog.update({a:2},{$set:{b:4}})

mongo_lib:update(blog, {a,2}, {<<"$set">>,{b,4}})

$inc 用来增加已有的键的值,或者在键不存在时创建一个键,只要用于数值变化的地方

3.2 数组修改器

使用这一类修改器可用于操作数组。

$push用于向数组末尾添加一个元素,搭配$ne用来实现如果一个值不在数组里面就把它加进去

db.blog.update({a:{$ne:2}},{$push:{b:2}})

可以用$addToSet直接实现同样的事,搭配$each可以添加多个不同的值

db.blog.update({a:1},{$addToSet:{"emails":{$each:["1@qq.com,2@qq.com"]}}})

{$pop:{key:1}}从数组末尾删除一个元素 {$pop:{key:-1}}从头删除

使用$pull可以基于特定项执行删除, 会将所有匹配的部分删除,如[1,1,2,1]执行pull 1 得到 [2]

db.lists.update({},{"$pull":{"todo":"laundry"}})

如果数组有多个值,我们可以使用定位操作符来对一部分进行操作

db.blog.update({a:1},{$inc:{"b.0.votes":1}}) //使用数组下标

但是很多情况不预先查询文档就不知道要修改数组的下标,可以这样

db.blog.update{{"b.name":"john"},{$set:{"b.$.name":"jim"}}} 但是注意这样只会更新第一个匹配的元素

3.3 upsert

upsert属于一种特殊更新,要是没有文档符合更新条件,就会以这个条件和更新文档为基础创建一个新的文档,如果找到了,就正常更新。update的第三个参数就是这个upsert,取值true or false

3.4 更新多个文档

默认情况,更新只能对符合条件的第1个文档执行操作,要是多个文档符合,其余的文档就没有变化,可以设置update的第4个参数为true

4 查询

db.users.find({age:{"$gte":18, "$lte":30}})

db.raffle.find({"$or":[{"ticket_no:725"},{"winner":true}]})

db.raffle.find({"$or":[{ticket_no:{$in:[123,345]}}, {winner:true]})

$mod 会将查询的值除以第一个给定值,若余数等于第二个给定值则返回结果

db.user.find({"id_num": {$not : {$mod : [5,1]}}})

条件句的规则

以$开头的键在不同的位置,基本可以肯定:条件句是内层文档的键,而修改器则是外层文档的键

一个键可以有多个条件,但是同一个键不能对应多个更新修改器。

null可以匹配自身,而且可以匹配不存在的,所以如果仅仅想要匹配键值为null的文档,既要检查该键是否为null,还要通过¥exists条件判定键值已经存在:

db.c.find({"z":{$in:[null],"$exists":true}})

mongo_lib:find(test, {z, {<<"$eq">>, null, <<"$exists">>, true}})

4.3 正则表达式

mongo使用Perl兼容的正则表达式(PCRE)库来匹配正则表达式,其能有效地匹配字符串

db.posts.find({post_text:{$regex:"runoob","$options":"$i"}}) //不区分大小写查找字符串runoob

如果文档中字段设置了索引,那么使用索引相比于正则表达式匹配查找所有的数据查询速度更快

4.3.1 查询数组

数组绝大多数可以这样理解:每一个元素都是整个键的值

如果需要多个元素来匹配数组,就要用$all了。db.food.find({fruit:{$all:["apple","banana"]}})

精准匹配 db.food.find({"fruit":["apple","banana","peach"]}) 必须要完全匹配

$size 查询指定长度的数组

$slice可以指定返回数组的一个子集合 db.blog.find({},{b:{$slice:[3,1]}})

4.3.2 查询内嵌文档

db.people.find({"name.first":"Joe","name.last":"Schmoe"})

对于更复杂的文档,要正确地指定一组条件,而不用指定每个键,需要使用$elemMatch,这种模糊的命名条件句能用来部分指定匹配数组中的单个内嵌文档的限定条件。

db.blog.find({"comments":{$elemMatch:{"author":"joe","score":{$gte:5}}}})

$elemMatch将限定条件进行分组,仅当需要对一个内嵌文档的多个键操作时才会用到

索引

(ensureIndex被废除,现在是createIndex的别名)创建索引:db.foo.ensureIndex({"a":1, "b":-1, "c":1},{"name":alphabet}) //自定义索引名

唯一索引:确保集合的每一个文档的指定键都有唯一值。db.people.ensureIndex({“username”:1},{"unique":true}),如果没有对应的键,索引会将其作为Null存储,所以如果对某个键建立了唯一索引,但插入了多个缺少索引键的文档,则由于文档包含null值而导致插入失败。

(新版本已经不支持dropDups了)创建唯一索引时,如果有些值已经重复了,可能希望将所有包含重复值的文档都删掉,dropDups选项就可以保留第一个发现的文档,而删除接下来有重复值的文档:db.peopel.ensureIndex({"username":1},{"unique":true, "dropDups":true}) 

查看集合索引:db.col.getIndexes() 删除索引: db.col.dropIndexes() db.col.dropIndex(“索引名称”)

使用background可以使索引的创建放到后台完成,同时正常处理请求

使用expireAfterSeconds参数来对数据进行失效时间设置

所指定的键必须为时间类型

1.创建索引,设置过期时间

db.foo.createIndex({"createAt":1},{expireAfterSeconds:3600}) mongodb会在大于3600S后过期

2.建立索引,设置expireAfterSeconds为0

db.foo.createIndex({"expireAt":1}, {expireAfterSeconds:0}) 等待时间到达expireAt的值时,这个文档失效

 

聚合

db.mycol.aggregate([{$group:{_id:"$by_user", num_tutorial:{$sum:1}}}])

mongo 管道 

db.article.aggregate(
    { $project : {
        title : 1 ,
        author : 1 ,
    }}
 );

 

 

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!