MongoDB的介绍与常用方法简述

概述

MongoDB是一个面向文档型 (document-oriented) 的数据库, 与常规的关系型数据库相比,文档型数据库不再有行 (row) 的概念,取而代之的是更加灵活的文档 (document) 类型。通过在文档中嵌入文档和数据,面向文档型的数据库可以仅用一条记录就可以表现复杂的层次关系。而且MongoDB不需要预定义模式 (predefined schema),这使得删除和添加字段变得更加的容易,有利于开发者进行快速的迭代。

基础知识

文档

文档类似于传统关系数据库中的行,是MongoDB中最基本的数据单元。文档是由若干个键值对组成的一个有序集,类似于字典 { key:value, key:value}, 数据的键可以为任意UTF8字符,但是不能含有空字符 (\0)。
在MongoDB中,键值对是有序的。{ keyA:1, keyB:2 }和{ keyB:2, keyA:1 }是不同的。不过通常情况下字段的顺序并不重要,MongoDB会自动对字段重新排序。但是在一些特殊的情况下,字段的顺序就会变得很重要。

集合

集合类似于关系数据库中的表,用于存放一组文档。MongoDB中一个集合中的文档可以是各式各样的,不需要有统一的字段。
虽然MongoDB并没有强制要求,但是也不代表我们可以为所欲为的把所有数据都放在一个集合中,原因有4点

  1. 管理麻烦
  2. 拖慢查询效率
  3. 不同类型的文档数据分散在一个集合中,对磁盘寻道压力大
  4. 不利于建立索引(特别是唯一索引)

集合的命名通常是满足以下条件的UTF-8字符串

  1. 不能是空字符串 ("")
  2. 不能包含空字符 (\0)
  3. 不能已system.和$开头

组织集合可以使用 “.” 分割不同命名空间的子集合,比如blog.posts和blog.authors。这样可以使结构看起来更清晰,但是这两个集合本质上没有任何关系。

数据库

数据库就是存放多个集合的地方,一个MongoDB实例可以承载多个数据库,每个数据库都有独立的权限控制。数据库名只能由ASC2中的字母,数字和加减下划线组成,同时要避开MongoDB的数据库名保留字段admin,local 和config。数据库最终会变成储存在系统中的一个文件。

数据类型

MongoDB中的文档格式和JSON十分接近。JSON是一种简单的数据表示方式,仅包含六种数据类型:null,布尔,数字,字符串,数组和对象。MongoDB在保留JSON格式的基础上,添加了更加丰富的数据类型:

  • null :{“x” : null}
  • 布尔 :{“x” : true}
  • 数值 :{“x” : 3.14} 默认为64位的浮点型数值,也可以手动设置为NumberInt(“3”)和- - - NumberLong(“3”)
  • 字符串 :{“x” : “foobar”}
  • 日期 :{“x” : new Date() } 关于时间的函数 Date(), new Date()和ISODate()
  • 正则表达式:{“x” : /foobar/i}
  • 数组:{“x” : [1,2,3]} 数组内可以存放任意类型的数据
  • 内嵌文档:{“x” :{“x” : 1}}
  • 对象id:{ ObjectID() }
  • 二进制数据。二进制数据用于保存未知的文件类型
  • 代码:{“x” : function() { }}

MongoDB中的ID

MongoDB中储存的文档必须有一个"_id"键,id键值可以是任何类型的,默认是ObjectID对象。再一个集合中,每个文档的id都必须是唯一的。
ObjectID
ObjectID是_id的默认类型,由24个十六进制数组成的字符串,占用12字节的储存空间。ObjectID的0-3位是时间戳,4-6位是时间码,7-8位是PID,9-11位是计数器。所以如果连续的创建多个ObjectID,只有末尾的数字会变化。MongoDB采用ObjectID而不是自增id的原因是在多个服务器上维护这个自增id费时费力,而MongoDB在设计之初就是用作分布式数据库的,所以才采用了这种方式放不同的机器可以用全局唯一的方式生成。

安装

在服务器上安装mongoDB

添加一个yum源到目录/etc/yum.repos.d/下

[mongodb-org-4.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.0.asc

然后运行sudo yum install -y mongodb-org指令安装mongoDB

安装完成后启动服务以及配置开机自启动

sudo service mongod start
sudo chkconfig mongod on
systemctl enable mongod.service

OpenResty环境中安装lua_resty_mongo

将包中的cJSON上传到服务器上然后运行make file安装。然后把mongo.lua和libcjson.lua放到开发环境下,打开libcjson.lua文件修改第56行

local cjson = ffi_load "/usr/local/openresty/nginx/lua/lib/lua/5.1/libcjson.so"

将libcjson.so文件在服务器上正确的地址复制过来。
Mongodb_Adapter.lua是我自己自己写的一个方法集,用来调用lua_resty_mongo的api。

Insert方法

方法描述

在MongoDB shell中,插入数据使用的命令是db.col.insert( )
例如db.col.insert( {key:value} )

Mongodb_Adapter.Insert(collection,data,ordered)
输入参数:
  collection: string类型       想要插入的table的名称
  data: table类型         想要插入的数据,可以是一个字典或者是多个字典的集合
                          MongoDB支持在字段中嵌入子字段
  ordered(可选): 布尔类型 ordered为假时,插入文档失败不会继续插入后续文档
                         oredered为真时,插入单个文档失败会继续插入下一个
                         ordered默认为真
                         
Return ok,n_modified,log
返回内容:
  ok:          为真表示插入成功,为空表示插入失败
  n_modified:  插入指令的影响行数
  log:         错误描述(如果执行失败)

示例参考
Mongodb_Adapter.Insert(“ts_qk_customer_person”,
{{“person_id”:“123”,“field”:{“ok”:“ok”}},{“person_id”:“321”}},
true)

Find方法

方法描述

在MongoDB shell中,插入数据使用的命令是db.col.find( )
例如db.col.find( {key:value} )

Mongodb_Adapter.Find(collection,query, fields, num_to_skip,num_to_return)
输入参数:
  collection: string类型       想要插入的table的名称
  query: table类型        信息检索的条件
  fields: table类型       返回信息的字段
  num_to_skip:int类型     查出数据的offset
  num_to_return:int类型   返回数据的条数
                         
Return docs,n_matched,cursor
返回内容:
  docs:          返回的数据文档
  n_matched:     匹配的数据数量
  cursor:        cursor对象

常用查询语法

比较问题

在数据库查询时经常需要比较字段的值
$
$in可以用来查询一个键的多个值,例如find( { age : { $in : [1,2,3] }})
$nin可以用来查询一个键不包含多个值,例如find( { age : { $nin : [1,2,3] }})
$or则更通用一些,例如find({$or:[ {age : 1} , {age : 2} ] })
$and则是用拼接需要同时满足的条件的,例如find({$and:[ {age : 1} , {age : 2} ] })
$nor是用来表示不为任意一个条件find({$nor:[ {age : 1} , {age : 2} ] })
$regex则是用来执行正则匹配的find( { age : { $regex : abc, $options:m }})
$regex操作符中的option选项可以改变正则匹配的默认行为,它包括i, m, x以及S四个选项,其含义如下
i 忽略大小写,{<field>{$regex/pattern/i}},设置i选项后,模式中的字母会进行大小写不敏感匹配。
m 多行匹配模式,{<field>{$regex/pattern/,$options:'m'},m选项会更改^和$元字符的默认行为,分别使用与行的开头和结尾匹配,而不是与输入字符串的开头和结尾匹配。
x 忽略非转义的空白字符,{<field>:{$regex:/pattern/,$options:'m'},设置x选项后,正则表达式中的非转义的空白字符将被忽略,同时井号(#)被解释为注释的开头注,只能显式位于option选项中。
s 单行匹配模式{<field>:{$regex:/pattern/,$options:'s'},设置s选项后,会改变模式中的点号(.)元字符的默认行为,它会匹配所有字符,包括换行符(\n),只能显式位于option选项中。

$exists可以用来检查某个字段是否存在find({ age:{ $exists:true })
$all用来匹配一个数组既包含a,也包含b,例如find( age:{ $all: [1,2,3]})
$size用于匹配数组的长度。例如find( age:{ $size :3 }),但是该字段无法与比较字段一起使用。
$slice操作符用于给数组进行切片。例如find( age:{ $slice :3 } ), find( age:{ $slice : -3 } ),find( age:{ $slice :[1,3] } )
$elemMatch用于当使用比较字段查找数组里的数字时,限定数组中的一个元素必须满足所有的指定条件。例如 find( age: {$elemMatch : { $gt:10, $lt:20 }} )
$where字段可以使用JS来实现任意查询,性能损失非常严重应该避免使用,仅用于复杂查询。

高级查询语法

排序问题

在MongoShell中,排序是通过db.collection.find().sort( { age: -1 } )实现的。sort是集成在cursor实例中的一个方法。
$orderby字段可以让我们吧排序参数集成到query语句中,方便使用。
用法:

原句:db.collection.find().sort( { age: -1 } )
db.collection.find( { $query: {}, $orderby: { age : -1 } } )

索引问题

在MongoShell中,可以使用db.users.find().hint( { age: 1 } )指令来强制数据库引擎使用某一个索引。
$hint字段可以让把hint集成到query语句中。

原句:db.users.find().hint( { age: 1 } )
db.users.find( { $query: {}, $hint: { age : 1 } } )

不仅如此,MongoShell中还提供了db.collection.find().max( { age:100})和db.collection.find().min({age:1})来限制索引范围。
在query语句中使用 m a x 和 max和 maxmin字段也有同样的效果。

原句:db.collection.find().max( { age: 25 } )
db.collection.find( { $query: {}, $hint: { age : 1 },$max:{age:25} } )

原句:db.collection.find().min( { age: 25 } )
db.collection.find( { $query: {}, $hint: { age : 1 },$min:{age:25} } )

原句:db.collection.find().min( { age: 20 } ).max( { age: 25 } ).hint( { age: 1 } )
db.collection.find( { $query: {}, $hint: { age : 1 },$min:{ age:20 } , $max:{age:25} } )

特殊语法

$maxscan用于设置扫描文档的上限
find({ q u e r y : , query: {}, query:,maxscan:20)})
$showDiskLoc用于返回数据段在磁盘上的位置
find({ q u e r y : , query: {}, query:,showDiskLoc:true)})

Update方法

方法描述

在MongoDB shell中,更新数据使用的命令是db.col.update( )
例如db.col.update( find条件,要插入的数据 )

Mongodb_Adapter.Update(collection, query, update, upsert, multi, write_concern)
输入参数:
  collection: string类型       想要插入的table的名称
  query: table类型             查询语句
  update: table类型            更新语句
  upsert: 布尔类型              为真时,如果找不到需要更新的条目就插入一条新的数据。
  multi:布尔类型               是否要更新多条数据。
  write_concern               写安全参数
  
                         
Return 
返回内容:
  true表示更新成功

使用修改器

如果在update里直接填写文档,mongoDB会用你填入的文档替换掉本来的内容。但是我们在更新文档的时候通常只有一部分内容需要更新。这时就需要用到修改器。

$inc字段可以用来操作数字类型的字段,例如
update({ name: abc},{ $inc:{ age:1 } })
这个代码表示将age字段的数值加一,同理也可以输入负数

$set字段可以用来指定某一个字段的值,如果该字段不存在,就创建它。例如
update ({_id:1223} , {$set:{ name: abc }})
$set字段可以用来执行任意更新,甚至是数组
update ({_id:1223} , {$set:{ name: [name1.name2] }})

$unset字段可以用来删除文档中的某个字段,例如
update ({_id:1223} , {$unset:{ name: 1 }})

$push字段可以用于向一个已有的数组中推入一个新值,如果不存在数组则自动创建一个。例如
update ({_id:1223} , {$push:{ name: abc }})
如果想一次性向一个数组里推入多个值,可以用$each字段实现。例如
update ({_id:1223} , {$push:{ name: $each:[abc,efg,def] }})
如果你想让你的数组只能装固定个数的元素,可以使用$slice字段来实现。例如
update ({_id:1223} , {$push:{ name: $each:[abc,efg,def]
                                    $slice:10        }})
如果数组内元素小于$slice指定的个数

如果数组中的内容时一个子文档,则可以用$sort字段来指定用于排序的字段
update ({_id:1223} , {$push:{ people: $each:[{name:abc},{name:bed}]
                                    $slice:10
                                    $sort:{name:1}        }})
                                    
$addToSet可以保证添加数据时不会添加重复的值,可以和$each组合使用
update({_id:1223} , { $addToSet:{ name: $each:[123,122]})

$pop用于弹出数组任意一侧的值,值为-1就是从头部删除,1是从尾部删除
update({_id:1223} , { $pop:{ $key:1 }]})
$pull可以用于弹出指定元素
update({_id:1223} , { $pull:{ $key:key_name }]})

Delete方法

方法描述

在MongoDB shell中,更新数据使用的命令是db.col.deleteMany( )
例如db.col.deleteMany( find条件 )

Mongodb_Adapter.Delete(collection, query, limit, write_concern)
输入参数:
  collection: string类型       想要插入的table的名称
  query: table类型             查询语句
  limit: 数字类型               删除匹配文档的上限
  write_concern                写安全参数
  
                         
Return 
返回内容:
  true表示删除成功

Count方法

方法描述

在MongoDB shell中,统计数据使用的命令是db.col.find().count()
Mongodb_Adapter.Count(collection, query, limit, skip,hint)
输入参数:

  collection: string类型       想要插入的table的名称
  query: table类型             查询语句
  limit: 数字类型               匹配文档的上限
  skip:数字                    要跳过的数量
  hint:table                  手动指定索引
  
                         
Return 
返回内容就是匹配的条目数量
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值