MongoDB学习笔记

Mongo

MongoDB 是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。

MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。、

入门

安装Mongo

windows安装

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

linux安装

https://www.cnblogs.com/pfnie/articles/6759105.html

基本操作

创建数据库
use DATABASE_NAME   创建/切换数据库
查看当前所在库
db  查看当前所在库
查看所有库
show dbs    查看所有库
删除db
db.dropDatabase()   删除库(先进入库use dbname)
创建集合(表)
db.createCollection("tableName")
createCollection四个参数:

capped(布尔型):

如果为 true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。当该值为 true 时,必须指定 size 参数。

autoIndexId(布尔型):

如为 true,自动在 _id 字段创建索引。默认为 false。

size(数值型):

为固定集合指定一个最大值(以字节计)。如果 capped 为 true,也需要指定该字段。

max(数值型):

指定固定集合中包含文档的最大数量。

例子:

db.createCollection(
    "tablename1", 
    { 
        capped : true, 
        autoIndexId : true, 
        size :  6142800,
        max : 10000 
    } 
)
删除集合(表)
db.tableName.drop()
显示当前db状态
db.stats(); 
当前db版本
db.version(); 
查看命令提示
db.help();  db.tableName.help();  db.tableName.find().help();  

增删改查

插入文档

db.tableName.insert()

例子:

db.user.insert({ "name" : "zhangsan", "age" : 15})

查询文档

db.tableName.find()
两个参数:

query 条件

例子:

db.tableName.find({"name":"zhangsan"})

projection 返回文档的信息(返回的列)

例子:

db.tableName.find({"name":"zhangsan"}, {"name":0, "age":1})

注意:值只有0和1,1表示显示项,0表示不显示项

条件操作符
sql 语义 mongo 列子
> 大于 $gt db.tableName.find({"age":{$gt:15}})
< 小于 $lt
>= 大于等于 $gte
!= 不等于 $ne
in 在...里面 $in db.tableName.find({"name":{"$in":["zhangsan","lisi"]}})
or 或者 $or db.tableName.find({"gender": "boy", $or: [{"name": "zhangsan"})
$type操作符
类型 代号值
Double 1
String 2
Object 3
Array 4
Binary data 6
Object id 7
Boolean 8
Date 9
Null 10
JavaScript 13
模糊查询
正则匹配:

$regex
例子:

db.tableName.find({"name":{$regex:"zhang"}})

删除文档

db.tableName.remove(
   <query>,
   <justOne>
)

uery :(可选)删除的文档的条件。
justOne : (可选)如果设为 true 或 1,则只删除一个文档。

例子:

db.tableName.remove({"name":"zhangsan"})

更新文档

db.tableName.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
)

query : update的查询条件,类似sql update查询内where后面的。

update : update的对象和一些更新的操作符,也可以理解为sql update查询内set后面的。(https://blog.csdn.net/sunnyyoona/article/details/52420210)

upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
writeConcern : 可选,抛出异常的级别。

例子:

db.tableName.update({"name":"zhangsan"}, {"name":"wangwu", age:18})

分页排序

分页
limit与skip

limit(number) 读取指定数量数据

例子:

db.tableName.find().limit(2)  显示两条数据

skip(number) 跳过指定数量的数据

例子:

db.tableName.find().skip(2)  跳过前面两条数据,从第三条开始读取
排序

sort({KEY:1})

例子:

db.tableName.find().sort({"age" : -1}) 1升-1降

注意:skip(), limilt(), sort()三个放在一起执行的时候,执行的顺序是先 sort(), 然后是 skip(),最后是limit()。

索引

查看索引

getIndexes()            方法可以用来查看集合的所有索引
totalIndexSize()        查看集合索引的总大小

创建索引

字段索引
db.tableName.ensureIndex({KEY:1}, {options})

例子:

db.tableName.ensureIndex({"name" : 1})

keys,要建立索引的参数列表。如:{KEY:1},其中key表示字段名,1表示升序排序,也可使用使用数字-1降序。

options,可选参数,表示建立索引的设置。可选值如下:

参数 类型 描述
background Boolean 在后台建立索引,以便建立索引时不阻止其他数据库活动,默认值 false
unique Boolean 创建唯一索引,默认值 false
name String 指定索引的名称,如果未指定,MongoDB会生成一个索引字段的名称和排序顺序串联,名字长度限制为125字节
dropDups Boolean 创建唯一索引时,如果出现重复删除后续出现的相同索引,只保留第一个
sparse Boolean 对文档中不存在的字段数据不启用索引,默认值是 false
v index version 索引的版本号
weights document 索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重
复合索引

复合索引也称多字段索引

db.tableName.ensureIndex({"name":1,"age":-1})
多键索引

多键索引与单键索引创建形式相同,区别在于字段的值.值具有多个记录,例如数组。

db.tableName.insert({x:[1,2,3,4]})
过期索引

过期索引只能建立在时间类型上(时间数组也行,数字是以最小时间为标准),不能使用时间戳;不能是复合索引;删除时间不是非常精确(删除也需要时间)。

db.tableName.ensureIndex({"time":1},{expireAfterSeconds:10})
db.zhoucl.insert({"name":"zhangsan"+50, "age":14, "gender":"难","time":new Date()})
//插入数据十秒后将被删除
全文索引(文本索引)

能解决快速文本查找的需求,每张表只允许创建一个全文索引;全文索引只能指定一个$text;

普通全文索引
db.tableName.ensureIndex({"key":"text"})
多列全文索引
db.tableName.ensureIndex({"key":"text", "key2":"text"})
所有列
db.tableName.ensureIndex({"$**":"text"})

查询指定关键字:{"$search" : "查询关键字"}

查询多个关键字(或关系):{"$search" : "查询关键字 查询关键字 ......"}

查询多个关键字(与关系):{"$search" : ""查询关键字" "查询关键字" ......"}  # "转义字符

排除多个关键字(排除某一个):{"$search" : ""查询关键字" "查询关键字"...... - 排除关键字"}

相似度查询
db.tableName.find({$text:{$search:"aa bb"}}, {score:{$meta:"textSore"}}})
排序  
db.tableName.find({$text:{$search:"aa"}}, {score:{$meta:"textScore"}}).sort({score:{$meta:"textScore"}})
其他类型索引

哈希索引(Hashed Index) 是指按照某个字段的hash值来建立索引,目前主要用于MongoDB Sharded

Cluster的Hash分片,hash索引只能满足字段完全匹配的查询,不能满足范围查询等。

地理位置索引(Geospatial Index)能很好的解决O2O的应用场景,比如『查找附近的美食』、『查找某个区域内的车站』等。

聚合

aggregate主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。

aggregate()是基于数据处理的聚合管道,每个文档通过一个由多个阶段(stage)组成的管道,可以对每个阶段的管道进行分组、过滤等功能,然后经过一系列的处理,输出相应的结果。Mongo还提供了一些聚合函数如:count(),distinct()。

语法:

 db.collection.aggregate(pipeline, options)

gourp聚合:

group做的聚合有些复杂。先选定分组所依据的键,此后MongoDB就会将集合依据选定键值的不同分成若干组。然后可以通过聚合每一组内的文档,产生一个结果文档。

$group聚合相关表达式:
表达式 描述 实例
$sum 计算总和 db.mycol.aggregate([{group : {_id : "by_user", num_tutorial : {sum : "likes"}}}])
$avg 计算平均值 db.tableName.aggregate([{group : {_id : "by_user", num_tutorial : {avg : "likes"}}}])
$min 获取集合中所有文档对应值得最小值 db.tableName.aggregate([{group : {_id : "by_user", num_tutorial : {min : "likes"}}}])
$max 获取集合中所有文档对应值得最大值 db.tableName.aggregate([{group : {_id : "by_user", num_tutorial : {max : "likes"}}}])
$push 在结果文档中插入值到一个数组中 db.tableName.aggregate([{group : {_id : "by_user", url : {push: "url"}}}])
$addToSet 在结果文档中插入值到一个数组中,但不创建副本 db.tableName.aggregate([{group : {_id : "by_user", url : {addToSet : "url"}}}])
$first 根据资源文档的排序获取第一个文档数据 db.tableName.aggregate([{group : {_id : "by_user", first_url : {first : "url"}}}])
$last 根据资源文档的排序获取最后一个文档数据 db.tableName.aggregate([{group : {_id : "by_user", last_url : {last : "url"}}}])
例子1:

数据如下:

{_id: 1, title: 'MongoDB Overview', description: 'MongoDB is no sql database', by_user: 'runoob.com', url: 'http://www.runoob.com',tags: ['mongodb', 'database', 'NoSQL'],likes: 100},

{_id: 2, title: 'NoSQL Overview',  description: 'No sql database is very fast', by_user: 'runoob.com', url: 'http://www.runoob.com', tags: ['mongodb', 'database', 'NoSQL'], likes: 10},

{_id: 3, title: 'Neo4j Overview',  description: 'Neo4j is no sql database', by_user: 'Neo4j', url: 'http://www.neo4j.com', tags: ['neo4j', 'database', 'NoSQL'], likes: 750 }

聚合函数如下:

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

结果如下:

{ "_id" : "runoob.com", "num_tutorial" : 2}
{ "_id" : "Neo4j", "num_tutorial" : 1}
例子2:

数据如下:

{ "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-03-01T08:00:00Z") }
    
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "date" : ISODate("2014-03-01T09:00:00Z") }
    
{ "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-03-15T09:00:00Z") }
    
{ "_id" : 4, "item" : "xyz", "price" : 5, "quantity" : 20, "date" : ISODate("2014-04-04T11:21:39.736Z") }
    
{ "_id" : 5, "item" : "abc", "price" : 10, "quantity" : 10, "date" : ISODate("2014-04-04T21:23:13.331Z") }

聚合函数如下:

db.tableName.aggregate([
      {
        $group : {
           _id : { month: { $month: "$date" }, day: { $dayOfMonth: "$date" }, year: { $year: "$date" } },
           totalPrice: { $sum: { $multiply: [ "$price", "$quantity" ] } },
           averageQuantity: { $avg: "$quantity" },
           count: { $sum: 1 }
        }
      }
   ]
)

结果如下:

{ "_id" : { "month" : 3, "day" : 15, "year" : 2014 }, "totalPrice" : 50, "averageQuantity" : 10, "count" : 1 }
{ "_id" : { "month" : 4, "day" : 4, "year" : 2014 }, "totalPrice" : 200, "averageQuantity" : 15, "count" : 2 }
{ "_id" : { "month" : 3, "day" : 1, "year" : 2014 }, "totalPrice" : 40, "averageQuantity" : 1.5, "count" : 2 }

其他聚合:

count
db.tableName.find().count() 统计总数
distinct
db.collection_name.distinct(field,query,options) 去重复

管道

MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。

管道表达式:
表达式 描述
$project 修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档
$match 用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作
$limit 用来限制MongoDB聚合管道返回的文档数
$skip 在聚合管道中跳过指定数量的文档,并返回余下的文档
$unwind 将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值
$group 将集合中的文档分组,可用于统计结果
$sort 将输入文档排序后输出
$geoNear 输出接近某一地理位置的有序文档
例子:
db.test.aggregate(
        [
            { 
                $group : {
                    _id : "$by_user", 
                    num_tutorial : {
                        $sum : 1
                    }
                }
            },
            { $skip : 1 }
        ]
    )
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容

  • MongoDB 基本概念 数据库 MongoDB一个数据库包括多个集合,类似于MySQL中一个数据库包含多个表;一...
    唔代阅读 962评论 0 0
  • mongodb 深入学习笔记 mongodb基本知识 mongodb是介于关系型数据库与非关系型数据库之间的NoS...
    深思海数_willschang阅读 959评论 0 1
  • mongoDB简介 MongoDB是用C++语言编写的非关系型数据库。特点是高性能、易部署、易使用,存储数据十分方...
    AubreyXue阅读 658评论 2 3
  • Windows上的安装方法: 下载,安装,可以从customer自定义安装路径后,例如我设置的安装路径为"F:\M...
    cccshuang阅读 194评论 0 1
  • MongoDB常用操作 一、查询 find方法 查询所有的结果: select * from users;===d...
    止风者阅读 591评论 1 3