进阶-MongoDB 知识梳理

MongoDB

一、MongoDB简介

      MongoDB是一个高性能,开源,无模式的文档型数据库,是当前NoSql数据库中比较热门的一种。它在许多场景下可用于替代传统的关系型数据库或键/值存储方式。Mongo使用C++开发。Mongo的官方网站地址是:http://www.mongodb.org/,读者可以在此获得更详细的信息。

      MongoDB 文档数据库,存储的是文档(Bson的二进制化).

二、MongoDB安装

      http://www.runoob.com/mongodb/mongodb-window-install.html

三、MongoDB优点

  • 面向文档存储(类JSON数据模式简单而强大)
  • 动态查询
  • 全索引支持,扩展到内部对象和内嵌数组
  • 查询记录分析
  • 快速,就地更新
  • 高效存储二进制大对象 (比如照片和视频)
  • 复制和故障切换支持
  • Auto- Sharding自动分片支持云级扩展性
  • MapReduce 支持复杂聚合
  • 商业支持,培训和咨询

四、MongoDB缺点

  • 不支持事务(进行开发时需要注意,哪些功能需要使用数据库提供的事务支持)
  • MongoDB占用空间过大 (不过这个确定对于目前快速下跌的硬盘价格来说,也不算什么缺点了
  • MongoDB没有如MySQL那样成熟的维护工具,这对于开发和IT运营都是个值得注意的地方
  • 在32位系统上,不支持大于2.5G的数据(很多操作系统都已经抛弃了32位版本,所以这个也算不上什么缺点了,3.4版本已经放弃支持32 位 x86平台)

五、MongoDB特点

  • 内部执行引擎为JS解释器, 把文档存储成bson结构,在查询时,转换为JS对象,并可以通过熟悉的js语法来操作.

六、MongoDB和关系型数据库区别

  • 传统型数据库: 结构化数据, 定好了表结构后,每一行的内容,必是符合表结构的,就是说--列的个数,类型都一样.
  • mongo文档型数据库: 表下的每篇文档,都可以有自己独特的结构(bson对象都可以有自己独特的属性和值)

七、MongoDB注意事项

  数据类型是敏感的,在对数据进行判断的时候 一定要看好类型 字符串的一定要加‘‘ 数字则不用

八、MongoDB入门命令

  8.1: show dbs  查看当前的数据库

  8.2 use databaseName 选库

  8.2 show tables/collections 查看当前库下的collection

  8.3 如何创建库? Mongodb的库是隐式创建,你可以use 一个不存在的库 然后在该库下创建collection,即可创建库

  8.4 db.createCollection(‘collectionName’) 创建collection

  8.5 collection允许隐式创建 db.collectionName.insert(document);

  8.6 db.collectionName.drop() 删除collection

  8.7 db.dropDatabase();删除database

九、MongoDB CRUD 命令

  C

    介绍: mongodb存储的是文档,. 文档是bson格式的对象.

    语法: db.collectionName.insert(document);

    1: 增加单篇文档

    Db.collectionName.insert({title:’nice day’});

    2: 增加单个文档,并指定_id

    Db.collectionName.insert({_id:8,age:78,name:’lisi’});

    3. 增加多个文档

    db.collectionName.insert(

    [

      {time:‘friday‘,study:‘mongodb‘},

      {_id:9,gender:‘male‘,name:‘QQ‘}

    ]

  D

    语法: db.collection.remove(查询表达式, 选项);

    选项是指  {justOne:true/false},是否只删一行, 默认为false

    注意

    1: 查询表达式依然是个json对象

    2: 查询表达式匹配的行,将被删掉.

    3: 如果不写查询表达式,collections中的所有文档将被删掉.

    例1: db.stu.remove({sn:’001’});

    删除stu表中 sn属性值为’001’的文档

    例2: db.stu.remove({gender:’m’,true});

    删除stu表中gender属性为m的文档,只删除1行.

  U

    改谁? --- 查询表达式

    改成什么样? -- 新值 或 赋值表达式

    操作选项 ----- 可选参数

    语法: db.collection.update(查询表达式,新值,选项);

    例:

    db.news.update({name:‘QQ‘},{name:‘MSN‘});

    是指选中news表中,name值为QQ的文档,并把其文档值改为{name:’MSN’},

    结果: 文档中的其他列也不见了,改后只有_id和name列了.

    即--新文档直接替换了旧文档,而不是修改

    如果是想修改文档的某列,可以用$set关键字

    db.collectionName.update(query,{$set:{name:’QQ’}})

    修改时的赋值表达式

    $set  修改某列的值

    $unset 删除某个列 db.表名.update({条件表达式},{赋值表达式:{字段名}})

    $rename 重命名某个列

    $inc 增长某个列

    $setOnInsert 当upsert为true时,并且发生了insert操作时,可以补充的字段.

    Option的作用:

    {upsert:true/false,multi:true/false}

    Upsert---是指没有匹配的行,则直接插入该行.(和mysql中的replace一样)

    例:db.stu.update({name:‘wuyong‘},{$set:{name:‘junshiwuyong‘}},{upsert:true});

    如果有name=’wuyong’的文档,将被修改

    如果没有,将添加此新文档

    例:

    db.news.update({_id:99},{x:123,y:234},{upsert:true});

    没有_id=99的文档被修改,因此直接插入该文档

    multi: 是指修改多行(即使查询表达式命中多行,默认也只改1行,如果想改多行,可以用此选项)

    例:

    db.news.update({age:21},{$set:{age:22}},{multi:true});

    则把news中所有age=21的文档,都修改

  R

    语法: db.collection.find(查询表达式,查询的列);

    Db.collections.find(表达式,{列1:1,列2:1});

    例1:db.stu.find()

    查询所有文档 所有内容

    例2: db.stu.find({},{gendre:1})

    查询所有文档,的gender属性 (_id属性默认总是查出来)

    例3: db.stu.find({},{gender:1, _id:0})

    查询所有文档的gender属性,且不查询_id属性

    例3: db.stu.find({gender:’male’},{name:1,_id:0});

    查询所有gender属性值为male的文档中的name属性

    db.表名.find({条件表达式},{显示字段名(1:显示,0:隐藏) ‘,‘ 分割})

  查询表达式:

    1: 最简单的查询表达式

    {filed:value} ,是指查询field列的值为value的文档

    2: $ne --- != 查询表达式

    {field:{$nq:value}}

    作用--查filed列的值 不等于 value 的文档

    3: $nin --> not in

    4: $all

    语法: {field:{$all:[v1,v2..]}}

    是指取出 field列是一个数组,且至少包含 v1,v2值

    5: $exists

    语法: {field:{$exists:1}}

    作用: 查询出含有field字段的文档

    6: $nor,

    {$nor,[条件1,条件2]}

    是指  所有条件都不满足的文档为真返回

    7:用正则表达式查询 以”诺基亚”开头的商品

    例:db.goods.find({goods_name:/诺基亚.*/},{goods_name:1});

    8: 用$where表达式来查询

    例: db.goods.find({$where:‘this.cat_id != 3 && this.cat_id != 11‘});

    注意: 用$where查询时, mongodb是把bson结构的二进制数据转换为json结构的对象,

    然后比较对象的属性是否满足表达式.

    速度较慢

十、游标操作

    游标是什么\?

    通俗的说,游标不是查询结果,而是查询的返回资源,或者接口.

    通过这个接口,你可以逐条读取.

    就像php中的fopen打开文件,得到一个资源一样, 通过资源,可以一行一行的读文件.

    声明游标:

    var cursor =  db.collectioName.find(query,projection);

    Cursor.hasNext() ,判断游标是否已经取到尽头

    Cursor. Next() , 取出游标的下1个单元

    用while来循环游标

    var mycursor = db.bar.find({_id:{$lte:5}})

    while(mycursor.hasNext()) {

      printjson(mycursor.next());

    }

    例:

    // 声明游标

    var cursor = db.goods.find();

    // 循环游标

    for(var doc=true;cursor.hasNext();) { printjson(cursor.next());}

    也可以简写:

    for(var  cursor=db.goods.find(), doc=true;cursor.hasNext();) { printjson(cursor.next());}

    游标还有一个迭代函数,允许我们自定义回调函数来逐个处理每个单元.

    cursor.forEach(回调函数);

    例:

    var cursor = db.goods.find();

     var gettitle = function(obj) {print(obj.goods_name)}

    cursor.forEach(gettitle);

    游标在分页中的应用

    比如查到10000行,跳过100页,取10行.

    一般地,我们假设每页N行, 当前是page页

    就需要跳过前 (page-1)*N 行, 再取N行, 在mysql中, limit offset,N来实现

    在mongo中,用skip(), limit()函数来实现的

    如 var mycursor = db.bar.find().skip(9995);

    则是查询结果中,跳过前9995行

    查询第901页,每页10条

    则是 var mytcursor = db.bar.find().skip(9000).limit(10);

    通过cursor一次性得到所有数据, 并返回数组.

    例:

    var cursor = db.goods.find();

    printjson(cursor.toArray());  //看到所有行

    printjson(cursor.toArray()[2]);  //看到第2行

    注意: 不要随意使用toArray()

    原因: 会把所有的行立即以对象形式组织在内存里.

    可以在取出少数几行时,用此功能

十一、索引

  1:索引提高查询速度,降低写入速度,权衡常用的查询字段,不必在太多列上建索引

  2. 在mongodb中,索引可以按字段升序/降序来创建,便于排序

  3. 默认是用btree来组织索引文件,2.4版本以后,也允许建立hash索引.

  查看查询计划

  db.find(query).explain();

  常用命令:

  查看当前索引状态: db.collection.getIndexes();

  创建普通的单列索引:db.collection.ensureIndex({field:1/-1});  1是升续 2是降续

  删除单个索引

  db.collection.dropIndex({filed:1/-1});

  一下删除所有索引

  db.collection.dropIndexes();

  创建多列索引  db.collection.ensureIndex({field1:1/-1, field2:1/-1});

  创建子文档索引

  db.collection.ensureIndex({filed.subfield:1/-1});

  创建唯一索引:

  db.collection.ensureIndex({filed.subfield:1/-1}, {unique:true});

  创建稀疏索引:

  稀疏索引的特点------如果针对field做索引,针对不含field列的文档,将不建立索引.

  与之相对,普通索引,会把该文档的field列的值认为NULL,并建索引.

  适宜于: 小部分文档含有某列时.

  db.collection.ensureIndex({field:1/-1},{sparse:true});

  db.tea.find();

  { "_id" : ObjectId("5275f99b87437c610023597b"), "email" : "[email protected]" }

  { "_id" : ObjectId("5275f99e87437c610023597c"), "email" : "[email protected]" }

  { "_id" : ObjectId("5275f9e887437c610023597e"), "email" : "[email protected]" }

  { "_id" : ObjectId("5275fa3887437c6100235980") }

  如上内容,最后一行没有email列,

  如果分别加普通索引,和稀疏索引,

  对于最后一行的email分别当成null 和 忽略最后一行来处理.

  根据{email:null}来查询,前者能查到,而稀疏索引查不到最后一行.

  创建哈希索引(2.4新增的)

  哈希索引速度比普通索引快,但是,无能对范围查询进行优化.

  适宜于---随机性强的散列

  db.collection.ensureIndex({file:’hashed’});

  重建索引

  一个表经过很多次修改后,导致表的文件产生空洞,索引文件也如此.

  可以通过索引的重建,减少索引文件碎片,并提高索引的效率.

  类似mysql中的optimize table

  db.collection.reIndex()

索引的一些知识点

  普通索引采用二叉树来进行查找
  不加索引 如果表内1000个数据 我要获取第99条 直接读到99(一条条读)
  加索引 直接采用二叉树
  哈希索引 直接生成Hash值 直接找到 速度快 
  但是如果是数据多 硬盘速度跟不上 Hash速度并没有比普通索引快多少 因为值都随机放到磁盘中某个位置上 还要进行查找 很消耗性能

索引提高查询速度,降低写入速度,权衡常用的查询字段,不必在太多列上建索引

2. 在mongodb中,索引可以按字段升序/降序来创建,便于排序

3. 默认是用btree来组织索引文件,2.4版本以后,也允许建立hash索引.

时间: 2024-10-11 18:12:06

进阶-MongoDB 知识梳理的相关文章

指针知识梳理7- 函数指针

一.函数的地址 前面讲 程序运行起来以后,在内存中有代码区,程序运行每一条指令,是从内存中读出来这条指令,然后再运行. 所谓函数的地址是指函数的入口地址,这个函数的从这个地址開始进入运行,也就是从这个地址处取指令运行. 那么在代码层面,函数的地址用 函数指针变量 来存储. 二.基本使用 1.函数指针定义 函数指针的定义,在语法看起来略微有点怪,仅仅须要记住形式 返回值 (*指针变量名)(形參类型): 比方,下面4个函数 void func1(void) { } int func2(void) {

[SQL] SQL 基础知识梳理(一)- 数据库与 SQL

SQL 基础知识梳理(一)- 数据库与 SQL [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5902856.html 序 目录 What's 数据库 数据库结构 SQL 概要 创建表 删除和更新表 1-1 What's 数据库 1.数据库(Database,DB):将大量数据保存起来,通过计算机加工而成的可以进行高效访问的数据集合.如:大型-银行存储的信息,小型-电话簿. 2.数据库管理系统(Batabase Management Syste

JavaScript基础知识梳理--数组

JavaScript基础知识梳理--数组 1.创建方法 空数组:var obj=new Array(); 指定长度数组: var obj=new Array( size ); 指定元素数组 :  var obj=new Array( 元素1,元素2,....): 单位数组:var obj=new Array[ 元素1,元素2,元素3,...,元素N]; 多维数组:var a=new Array( [数组1],[数组2],[数组3],...,[数组N] ); 2.基本操作 存取数组元素: 单维数组

Java基础知识梳理《一》

一.Java数据类型(简单称之为“四类八种”) java 基本的数据类型长度都是固定的,好处是在实现跨平台时就统一了. 1.整型 byte short int long (分别是1,2,4,8个字节) 类型 存储需求 位数 取值范围 byte 1字节 8位 -128~127 short 2字节 16位 -2^15 ~2^15-1 int 4字节 32位 -2^31~2^31-1 long 8字节 64位 -2^63~2^63-1 当超出int表示范围时,应该使用long型,添加后缀一大写的L 注

struts2 知识梳理

一:struts.xml配置详解: 1.<include> 表示引入其他配置文件 2.<constant> 定义常量 3.<package>:  属性 是否必需 描述name 是 包名,作为其它包应用本包的标记extends 否 设置本包继承其它包namespace 否 设置包的命名空间,会改变url,abstact 否 设置为抽象包 4<action>和<result> <action>有name,class,method,conv

指针知识梳理6-const与指针

const 定义的变量为只读变量,在语法层面上通过这个变量去修改内存是不允许的. 但是对于以下代码,就有很多人绕了: const int  *p1;  //p1能变,*p1不能变 int const  *p2;  //p2能变,*p2不能变 int *const  p3;  //p3不能变,*p2能变 我们通过代码来验证说明这三种写法: </pre><p></p><pre> #include <stdio.h> int main() { int

[SQL] SQL 基础知识梳理(四) - 数据更新

SQL 基础知识梳理(四) - 数据更新 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5929786.html 目录 一.插入数据 1.INSERT 语句的基本语法 --语法: --INSERT INTO <表名>(列1, 列2, ...) VALUES (值1, 值2, ...) INSERT INTO dbo.Shohin ( shohin_id , shohin_mei , shohin_bunrui , hanbai_tanka , s

[C#] C# 6.0 的知识梳理(整理中)

C# 6.0 的知识梳理 序 目前最新的版本是 C# 7.0,VS 的最新版本为 Visual Studio 2017 RC,两者都尚未进入正式阶段.C# 6.0 虽说出了一段时间,但是似乎有许多园友对这一块知识并不了解,如拼接字符串的 $ 符号,在此,小人献上拙作一篇<C# 6.0 的知识梳理>,祝大家在新的一年里:年年有今日,岁岁有今朝,月月涨工资,周周中彩票,天天好心情,日日好运道,白天遇财神,夜晚数钞票. 好了,废话不多说,我们先来回顾一下 C# 的版本史.后续我会对带 0 的版本号进

[SQL] SQL 基础知识梳理(三)- 聚合和排序

SQL 基础知识梳理(三)- 聚合和排序 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5926689.html 目录 一.对表进行聚合查询 1.聚合函数 (1)5 个常用函数: ①COUNT:计算表中的记录(行)数. ②SUM:计算表中数值列的数据合计值. ③AVG:计算表中数值列的数据平均值. ④MAX:求出表中任意列中数据的最大值. ⑤MIN:求出表中任意列中数据的最小值. (2)聚合:将多行汇总成一行. 图1-1 Shohin 表 2.计算