MongoDB入门

docker 安装MongoDB

//查找MongoDB镜像
docker search mongo
//拉取镜像
docker pull mongo
//查看下载来的MongoDB
docker inspect mongo:latest

编辑docker-compose.yml文件

[root@localhost mongodb]# more docker-compose.yml 
version: '2'
services:
 mongodb:
  image: mongo:latest
  volumes:
   - "./configdb:/data/configdb"
   - "./db:/data/db"
  ports:
    - "27017:27017"

docker-compose up -d 启动即可

启动MongoDB
mongod -dbpath=/root/mongodb/mongodb/data/db -port=27017
启动之后可以用 mongo命令连接MongoDB

插入数据:
db.runoob.insert({x:10})
直接将数据保存到runoob集合中,无需预先创建
db.runoob.find() 查找数据
db.runoob.findOne() 查找集合中的一个元素

image.png

show dbs 显示所有的数据库列表
db 显示当前使用的数据库
use local 将使用的数据库切换到local
db.dropDatabase() 删除当前的数据库

  • 几个特殊的保留数据库

admin: 从权限的角度来看,这是"root"数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。
local: 这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合
config: 当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。

文档以BSON的格式存储,文档有一下几个注意点:

  1. 文档中的键/值对是有序的
  2. 文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档)
  3. MongoDB区分类型和大小写。
  4. MongoDB的文档不能有重复的键。
  5. 文档的键是字符串。除了少数例外情况,键可以使用任意UTF-8字符。

  • BSON 与JSON的区别:
    BSON是在JSON上改造优化而成,主要有以下3点改进:
  1. 更快的遍历速度
    将json的每一个元素的长度存在元素的头部,这样只需要读取到元素长度就能直接seek到指定的点上进行读取了,从而加快了文档的遍历
  2. 操作更简易
    对json来说,数据存储是无类型的,比如你要修改基本一个值,从9到10,由于从一个字符变成了两个,所以可能其后面的所有内容都需要往后移一位才可以。
      而使用bson,你可以指定这个列为数字列,那么无论数字从9长到10还是100,我们都只是在存储数字的那一位上进行修改,不会导致数据总长变大。
      当然,在mongoDB中,如果数字从整形增大到长整型,还是会导致数据总长变大的
  3. 增加了额外的数据类型
    增加了“byte array”数据类型。这使得二进制的存储不再需要先base64转换后再存成json,大大减少了计算开销和数据大小
  • 总之:
    数据结构:
      json是像字符串一样存储的,bson是按结构存储的(像数组 或者说struct)
    存储空间
      bson>json
    操作速度
      bson>json。比如,遍历查找:json需要扫字符串,而bson可以直接定位
    修改:
      json也要大动大移,bson就不需要。

  • capped collections 固定大小的collection

有很高的性能以及队列过期的特性(过期按照插入的顺序),非常适合类似记录日志的功能,必须要显式的创建一个capped collection, 指定一个collection的大小,单位是字节,在capped collection能进行更新,然而,对象不能增加存储空间。如果增加,更新就会失败,数据库不允许进行删除。使用drop()方法删除collection所有的行。删除之后必须再显式的创建

  • MongoDB数据类型
数据类型 描述
String 字符串。存储数据常用的数据类型。在 MongoDB 中,UTF-8 编码的字符串才是合法的。
Integer 整型数值。用于存储数值。根据你所采用的服务器,可分为 32 位或 64 位。
Boolean 布尔值。用于存储布尔值(真/假)。
Double 双精度浮点值。用于存储浮点值。
Min/Max keys 将一个值与 BSON(二进制的 JSON)元素的最低值和最高值相对比。
Array 用于将数组或列表或多个值存储为一个键。
Timestamp 时间戳。记录文档修改或添加的具体时间。
Object 用于内嵌文档。
Null 用于创建空值。
Symbol 符号。该数据类型基本上等同于字符串类型,但不同的是,它一般用于采用特殊符号类型的语言。
Date 日期时间。用 UNIX 时间格式来存储当前日期或时间。你可以指定自己的日期时间:创建 Date 对象,传入年月日信息。
Object ID 对象 ID。用于创建文档的 ID。
Binary Data 二进制数据。用于存储二进制数据。
Code 代码类型。用于在文档中存储 JavaScript 代码。
Regular expression 正则表达式类型。用于存储正则表达式。
  • ObjectID 组成


    image.png
> var newObject = ObjectId()
> newObject.getTimestamp() //得到创建时间
ISODate("2018-06-09T13:18:48Z")
> newObject //查看对象值
ObjectId("5b1bd3b8b4852af9d8e13020")
> newObject.str //转换为字符串
5b1bd3b8b4852af9d8e13020
  • 日期:
> var mydate1 = new Date() //格林尼治时间
> mydate1
ISODate("2018-06-09T13:23:39.243Z")
>  var mydate2 = ISODate()
> mydate2
ISODate("2018-06-09T13:23:56.868Z")
> typeof mydate1 //查看类型
object
> var mydate1str = mydate1.toString() //转成字符串
> mydate1str
Sat Jun 09 2018 21:23:39 GMT+0800 (CST)
> typeof mydate1str
string
> Date() //查看当前日期
Sat Jun 09 2018 21:24:53 GMT+0800 (CST)

  • 连接的标准URL格式
    mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
    例子:
//连接到test数据库
mongodb://admin:123456@localhost/test
//连接 replica pair, 服务器1为example1.com服务器2为example2。
mongodb://example1.com:27017,example2.com:27017
//连接 replica set 三台服务器, 写入操作应用在主服务器 并且分布查询到从服务器。
mongodb://host1,host2,host3/?slaveOk=true
//直接连接第一个服务器,无论是replica set一部分或者主服务器或者从服务器。
mongodb://host1,host2,host3/?connect=direct;slaveOk=true
//安全模式连接到localhost:
mongodb://localhost/?safe=true
//以安全模式连接到replica set,并且等待至少两个复制服务器成功写入,超时时间设置为2秒。
mongodb://host1,host2,host3/?safe=true;w=2;wtimeoutMS=2000

  • MongoDB 数据操作
  • 集合
  1. 创建集合
    db.createCollection("runoob")
    db.col2.insert({"name":"zzj"})
//创建固定集合 mycol,整个集合空间大小 6142800 KB, 文档最大个数为 10000 个。
>  db.createCollection("mycol", { capped : true, autoIndexId : true, size :  6142800, max : 10000 } )
{
    "note" : "the autoIndexId option is deprecated and will be removed in a future release",
    "ok" : 1
}
> db.mycol.drop() //删除集合
true

  1. 查看所有的集合
    show collections
  2. 删除集合
    db.mycol.drop()
  • 文档
//切换数据库
use test
//保存数据
db.test.insert({"name":"zzj","age":18})
//查找集合
db.test.find();
//定义一个文档
var document=({title: 'MongoDB 教程', 
    description: 'MongoDB 是一个 Nosql 数据库',
    by: '菜鸟教程',
    url: 'http://www.runoob.com',
    tags: ['mongodb', 'database', 'NoSQL'],
    likes: 100
});
db.col.insert(document);
db.col.find();
//3.2版本后可以插入一条文档数据
var document=db.collection.insertOne({"a":"test"});
document
//3.2版本后一次插入多个文档数据
var res = db.collection.insertMany([{"b":3},{"c":4}]);
res

  • 修改文档

//文档更新
db.collection.update(
{"name":"zzj100001"}, //相当于where条件
{"$set":{"age":"19"}}, // 相当于set
{
"upsert":true, //是否新增,true表示没有找到会新增一行,默认为false
"multi":true //true更新找到的全部记录,false为一条记录
}
);
db.collection.find({"name": /zzj/});

//更新整个文档
db.collection.save(
{
    "_id" : ObjectId("5b1f3689ca00cba7f8960a2b"),
    "name" : "zzj100003",
    "age" : "19",
    "parents":[
        {"name":"zzold"},
        {"name":"zzyong"}
        ]
    
}
);
  • 删除文档

//删除整个集合数据
db.col.remove({});
db.col.find();
db.collection.find({"b":{"$gt":3}}).count();
//删除一部分(指定条件)数据
db.collection.remove(
{"b":{"$gt":3}},
{"justOne":true} //true只删除匹配到的一个
);
db.collection.remove(
{"b":{"$gt":3}},
{"justOne":false} //false 删除匹配到的全部数据
);
//remove方法已经过时,现在推荐deleteOne,deleteMany
//全部删除
db.col.deleteMany({});
db.collection.find({"b":{"$lte":3}}).count();
//删除一个
db.collection.deleteOne({"b":{"$lte":3}}); 
//删除指定条件的
db.collection.deleteMany({"b":{"$lte":3}});
  • 查询文档
操作 格式 范例 RDBMS中的类似语句
等于 {<key>:<value>} db.col.find({"by":"菜鸟教程"}).pretty() where by = 'xxx'
小于 {<key>:{$lt:<value>}} db.col.find({"likes":{$lt:50}}).pretty() where likes < 50
小于或等于 {<key>:{$lte:<value>}} db.col.find({"likes":{$lte:50}}).pretty() where likes <= 50
大于 {<key>:{$gt:<value>}} db.col.find({"likes":{$gt:50}}).pretty() where likes > 50
大于或等于 {<key>:{$gte:<value>}} db.col.find({"likes":{$gte:50}}).pretty() where likes >= 50
不等于 {<key>:{$ne:<value>}} db.col.find({"likes":{$ne:50}}).pretty() where likes != 50

//查找 collection 集合中name 包含 zzj的文档
db.collection.find({"name":/zzj/});
// ---------and-----------
//查找 collection 集合中name 包含 zzj并且年龄大于"18"的文档,注意"18"的类型
db.collection.find({"name":/zzj/,"age":{"$gte":"18"}});
//----------or------------
//查找 collection 集合中 name等于zzj1或者年龄等于18的数据
db.collection.find({"$or":[
{"name":"zzj1"},
{"age":18}
]});

db.collection.find({"b":{"$gt":3}});
//查找 collection 集合中 b 大于3 或者 (名字等于zzj1并且年龄为18) 的数据
db.collection.find({
    "b":{"$gt":3},
    "$or":[
        {"name":"zzj1"},
        {"age":18}
        ]
});

db.col.find({"likes": {$gt:50}, 
    $or: [{"by": "菜鸟教程"},{"title": "MongoDB 教程"}]
})

//只显示name和age字段,不显示_id一段
db.collection.find(
 {"b":{"$gt":3}},
 {"name":1,"age":1,"_id":0}
);

//不显示age和_id字段
//需要注意的是如果设置 0 的话那就都要设置0,设置1(可见)那就都要设置1,_id是个例外,哪个用它都可以
db.collection.find(
 {"b":{"$gt":3}},
 {"age":0,"_id":0}
);
//查找集合中age字段为String类型(等于2)
 //类型值参考http://www.runoob.com/mongodb/mongodb-operators-type.html
 db.collection.find({"age": {"$type":2}});
 //跳过5行,返回后面的50行
 db.collection.find({"c":{"$gt":3}}).skip(5).limit(50);
 //排序,1为升序,-1为降序
 db.collection.find().sort({"age":-1}).limit(5);
 //分析查询计划
 db.collection.find().sort({"age":-1}).limit(5).explain();
 db.collection.find().count();
  • 创建索引

 //创建索引,1为升序,-1为降序
 db.collection.createIndex({"name":1},{"name":"col_1"})
 //后面这个name 指定索引名称
 db.collection.createIndex({"name":-1},{"name":"col_-1"})
 //查看集合collection所有的索引信息
 db.collection.getIndexes();
 
 //创建唯一索引,数据不符合会报错
 db.collection.createIndex({"age":1},{"unique":true,"background":true});
 //创建唯一索引,是否删除重复记录,指定 true 创建唯一索引,默认值为 false会报错.
 db.collection.createIndex({"age":1},{"unique":true,"background":true,"dropDups":true,"name":"age_1"});
 //删除集合 collection 中名称为 col_-1 的索引
 db.collection.dropIndex("col_-1");
 //查看索引总大小
 db.collection.totalIndexSize();
 //删除集合中所有的索引
 db.collection.dropIndexes()
 db.collection.insert(
 {
   "post_text": "enjoy the mongodb articles on Runoob",
   "tags": [
      "mongodb",
      "runoob"
   ]
}
 );
//创建全文检索索引
db.collection.ensureIndex({post_text:"text"})
//全文检索,这个搜索 runoob有,搜索 runoo就没有
db.collection.find({$text:{$search:"runoob"}}) //找得到
db.collection.find({$text:{$search:"runoo"}}) //没找到
  • 聚合

//聚合
db.mycol.insertMany([
{
   title: 'MongoDB Overview', 
   description: 'MongoDB is no sql database',
   by_user: 'runoob.com',
   url: 'http://www.runoob.com',
   tags: ['mongodb', 'database', 'NoSQL'],
   likes: 100
},
{
   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
},
{
   title: 'Neo4j Overview', 
   description: 'Neo4j is no sql database',
   by_user: 'Neo4j',
   url: 'http://www.neo4j.com',
   tags: ['neo4j', 'database', 'NoSQL'],
   likes: 750
}
]);
//以字段 by_user分组,汇总条数
db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}])
//以字段 by_user分组,将 likes 字段的值累加起来
//类似 select by_user, count(*) from mycol group by by_user
db.mycol.aggregate([
    {"$group":{"_id":"$by_user","sum_value" :{"$sum":"$likes"}}}
]);
//平均值    
db.mycol.aggregate([
    {"$group":{"_id":"$by_user","sum_value" :{"$avg":"$likes"}}}
]);  
//最小值  
db.mycol.aggregate([
    {"$group":{"_id":"$by_user","sum_value" :{"$min":"$likes"}}}
]); 
//最大值  
db.mycol.aggregate([
    {"$group":{"_id":"$by_user","sum_value" :{"$max":"$likes"}}}
]);     

//push  将结果文档插入值到一个数组中,这个结果返回的Url是个数组,不会去重
db.mycol.aggregate([
    {"$group":{"_id":"$by_user","url":{"$push":"$url"}}}
    ]
)
//和push一样,Url是个数组,但是会去重    
db.mycol.aggregate([
    {"$group":{"_id":"$by_user","url":{"$addToSet":"$url"}}}
    ]
)
//第一个
db.mycol.aggregate([
    {"$group":{"_id":"$by_user","sum_value" :{"$first":"$likes"}}}
]);  
//最后一个
db.mycol.aggregate([
    {"$group":{"_id":"$by_user","sum_value" :{"$last":"$likes"}}}
]); 

数据类型
参考
springboot MongoDB源码示例参考
国外的一个例子
另一个java的MongoTemplate例子

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

推荐阅读更多精彩内容

  • 安装 MongoDB Windowns、Ubuntu17.10 下安装 MongoDB教程在此 MongoDB 帮...
    Kangvcar阅读 2,089评论 0 13
  • 第一章 前言 1.1 知识体系分析 前端工程师:Web前端,也就是在Web应用中用户可以看得见碰得着的东西。包括W...
    whitsats阅读 865评论 0 3
  • 一、什么是MongoDB MongoDB是一个介于关系数据库和非关系数据库(nosql)之间的产品,是非关系数据库...
    LemonnYan阅读 5,083评论 0 2
  • 1.express node Web应用框架,提供了很多Web应用和HTTP工具 使用express可以快速搭建一...
    寒梁沐月阅读 437评论 2 6
  • 1.express node Web应用框架,提供了很多Web应用和HTTP工具 使用express可以快速搭建一...
    昵称不能太随便阅读 1,321评论 0 2