关于MongoDB的学习

nosql之间的比较

memcached key-value缓存
redis key-value存储数据库
mongoDB 文档数据库,存储的是文档(Bson->json的二进制文件)
特点:内部执行引擎js解释器,把文档存储为bson结构,查询时,转换为JS对象,并可以通过熟悉的js语法来操作。

mongo和传统型数据库相比最大的不同

传统型数据库:结构化数据,定好了表结构后,每一行的内容,必须是符合表结构的,列的个数和类型都一样。
mongo文档型数据库:表下面的每篇文档都可以有自己独特的结构。

{
    mid:3,
    author: xxx,
    conment:  [
        {
            cid:97,
            content:'好电影!'
        },
        {
            cid:98,
            content:'确实好!',
            reply: [
                {
                    rid: 3,
                    content: '你说的对'
                }
            ]
        }
    ]
}

安装

  1. 下载mongodb www.mongodb.org 下载最新stable版
  2. 解压文件
  3. 不用编译,本身就是编译后的二进制可执行文件


    mongo可执行文件介绍
  4. 启动mongodb服务
/path/bin/mongod --dbpath /path/to/database --logpath /path/to/log-file --fork --port 27017

参数解释:

  • --dbpath 数据存储目录
  • --logpath 日志存储文件
  • --port 运行端口(默认27017)
  • --fork 后台进程运行
  1. mongodb非常占磁盘空间,刚启动要3-4G空间,如果用虚拟机练习,可能空间不够用,导致无法启动,可以用
--smallfiles 

选项来启动,将会占用较小空间,400M左右。

  1. 连接mongo
/path/bin/mongo

1. mongo入门命令

1.1 查看当前数据库

show dbs;

1.2 选库

use databaseName;

1.3 查看当前库下的表(在MySQL中叫tables,在mongo中叫collections)

show tables/collections;

1.4 mongo中use一个不存在的库时,会自动创建这个库(称为:隐式创建)

use dbname

1.5 显式创建一个表(如果你不创建,直接向其中加入一个文档,该Collection也会被隐式创建出来)

use dbname; //先选库
db.createCollection('name'); // 通过db对象的方法创建库

1.6 删除一个表(Collection)

use dbname; // 先选库
db.collectionName.drop(); // 通过db中collection对象的方法删除库

1.7 删除数据库

use dbname; //先选库
db.dropDatabase(); // 通过db对象的方法删除库

2. 基本操作-增删改查


  • 语法: db.collectionName.insert(document);
use dbname;
// 增加单个文档
db.collectionName.insert({title:'nice day'});
// 增加多个文档
db.collectionName.insert([
    {"title":"nice day"},
    {"name":"lili", "age":16}
]);
// 查看, 若没_id这个字段,mongo会自动增加这个字段
db.collectionName.find();

  • 语法: db.collectionName.remove(查询表达式,选项);
use dbname;
// 这条会报错
db.collectionName.remove();
// 全部删除
db.collectionName.remove({});
// 删除name为lili的数据
db.collectionName.remove({"name":"lili"});
// 删除age为19的数据,所有age=19的数据都会被删除
db.collectionName.remove({"age":19});
// 只删一条age为19的数据
db.collectionName.remove({"age":19}, true);

  • 语法: db.collectionName.update(查询表达式,新值,选项);
    选项 {upset:true/false, multi:true/false}
    upsert 是指没有匹配的行,则直接插入该行
    multi 是指修改多行(即使查询表达式命中多行,默认也只改1行,如果想修改多行,可以用此选项)
use dbname;
// 将name=lilei的数据age改为32,这里会将这条数据变为只有_id和age的数据!
db.collectionName.update({"name":"lilei"}, {"age":32});
// 修改单个字段的正确方式$set
db.collectionName.update({"name":"lilei"}, {$set:{"age":32}});
// 修改单个字段并添加选项
db.collectionName.update({"name":"lilei"}, {$set:{"age":32}}, {upsert: true});

  • 语法:
    db.collectionName.find(查询表达式,选项);
    db.collectionName.findOne(查询表达式,选项);
use dbname;
// 查询所有,展示所有列
db.collectionName.find();
// 带表达式和选项,选项表示要查age列(_id始终都有)
db.collectionName.find({"name": "hmm"}, {"age": 1});
// 查询一行
db.collectionName.findOne({"age": 1});

3. 查询表达式

  1. 最简单的查询表达式 { field : value}
    查询field为value的文档。
  2. $ne 不等与
    语法: { field : {$ne : value}}
use dbname;
// 查询age≠19的数据
db.collectionName.find({"age": {$ne:19}});
  1. $in 在某数组中
    语法: { field : {$in : [value1, value2, ....]}}
use dbname;
// 查询goods表中cat_id为2或8的文档
db.goods.find({"cat_id" : {$in : [2, 8]}});
  1. $nin 不在某数组中 not in
    语法: { field : {$nin : [value1, value2, ....]}}
use dbname;
// 查询goods表中cat_id不为2或8的文档
db.goods.find({"cat_id" : {$nin : [2, 8]}});
  1. $all field的值为数组,且至少包含所给值
    语法: { field : {$all : [value1, value2, ....]}}
  2. $exists 查询含有某字段的文档
    语法: { field : {$exists : 1}}
use dbname;
// 查找含有age字段的文档
db.collection.find({"age" : {$exists:1}});
  1. $nor 返回所有条件都不满足的文档
    语法: { $nor : [条件1, 条件2]}
  2. 正则表达式查询
use dbname;
// 查询产品名以诺基亚开头的文档
db.collectionName.find({"goods_name" : /诺基亚.*/}, {"goods_name" : 1});
  1. $where 表达式查询
    注意:用$where查询时,mongodb是把bson结构转为json对象,然后比较对象的属性是否满足表达式,所以速度交慢。
use dbname;
// 查找cat_id≠3且cat_id≠11的文档
db.collection.find({$where : "this.cat_id != 3 && this.cat_id != 11"});

4. 游标操作

游标是什么?
通俗的说,游标不是查询结果,而是查询的返回资源或者接口,通过这个接口,你可以逐条读取。就像php中fopen打开文件,得到一个资源句柄一样,通过这个句柄,可以一行一行的读文件。

use dbname;
// 声明游标
var cursor = db.collectionName.find(query, projection);
// 判断游标是否已经取到尽头
cursor.hasNext(); 
// 取出游标的下一个单元,是bson结构,人无法识别
cursor.next();

// 用while来循环游标
var mycursor = db.bar.find({"_id" : {$gt: 5}});
while(mycursor.hasNext()) {
    // 通过printjson打印这个bson文档
    printjson(mycursor.next());
}

// foreach 也可以
mycursor.foreach(function (obj) {
    printjson(obj);
})

5. group分组(求平均,求和等)

方法: aggregate

db.goods.aggregate([
    // 匹配哪些行
    {$match: {}}, 
    // 针对哪个字段分组,别名:$field
    // 根据哪个字段求值 , 别名 : { $求值方法 : "$field"}
    {$group: {"bieMin": "$cat_id", "total" : {$sum: "$price"}}}, 
]);
mongoDB分组示意图

6. Map-Reduce(分布式的group)

相比aggregate聚合操作,Map-Reduce支持分布式的数据(大数据,在不同的地点、服务器上)。
先 map: 分类。
后 reduce: 统计。

use dbname;

// map 函数
var map = function () {
    // 将cat_id相同的文档的goods_number放一起
    // this指的是遍历的每条数据
    emit(this.cat_id, this.goods_number);
};

// reduce 函数
var reduce = function (cat_id, numbers) {
    // 分类好后,根据cat_id字段中的numbers来求和
    return Array.sum(numbers);
};

// 进行mapReduce操作,第三个参数表示将输出结果放到res这个表中
db.goods.mapReduce(map, reduce, {out:"res"});
// 查看结果
db.res.find();
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 161,873评论 4 370
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,483评论 1 306
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,525评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,595评论 0 218
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,018评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,958评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,118评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,873评论 0 208
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,643评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,813评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,293评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,615评论 3 262
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,306评论 3 242
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,170评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,968评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,107评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,894评论 2 278

推荐阅读更多精彩内容