mongoDB(一)——mongoDB安装部署和常用shell命令
转 https://www.cnblogs.com/wyy1234/p/10919567.html#_labelTop
1.mongoDB简介
mongoDB 是由C++语言编写的,是一种分布式的面向文档存储的开源nosql数据库。nosql是Not Only SQL的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称。
mongoDB是无模式的文档数据库,在关系型数据库中,数据表的每一行都拥有一样的字段,字段的名字和数据类型在创建table的时候就基本确定了,如student表的每一行都有学生编号、学生姓名、年龄等字段;而在mongoDB中,存储数据的格式类似于Json(格式为Bson),每一个document的字段的名字和数据类型可以完全不同,如在一个collection下,第一个document可以存储学生信息(学生编号、姓名、年龄、性别等),第二个document可以存储班级信息(班级编号,班级名等)。正是因为无模式的特点,让我们可以无需多余操作就能完成数据的横向扩展。下表是mongoDB和传统数据库术语的对应关系。
| SQL术语 | MongoDB | 解释/说明 |
|---|---|---|
| database | database | 数据库 |
| table | collection | 数据库表/集合 |
| row | document | 数据记录行/文档 |
| column | field | 数据字段/域 |
| index | index | 索引 |
| join | $lookup | 表连接 |
| primary key | primary key | 主键,MongoDB自动将_id字段设置为主键 |
2. mongoDB安装
1.安装mongoDB
mongoDB的安装步骤十分简单,下载地址:https://www.mongodb.com/download-center#community。如果我们想在Windows上安装mongoDB直接下载msi文件,双击安装即可。如果要将mongoDB安装在Linux系统上,步骤如下:

####第1步 下载解压mongdb
#下载解压二进制包,解压即安装
cd /usr/local/src/
curl -O https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.0.9.tgz
tar -zxvf mongodb-linux-x86_64-4.0.9.tgz
mv mongodb-linux-x86_64-4.0.9 /usr/local/mongodb ####第2步 添加配置文件
vim /usr/local/mongodb/bin/mongodb.conf
配置文件内容如下:
systemLog:
destination: file
logAppend: true
path: /usr/local/mongodb/logs/mongodb.log
storage:
dbPath: /usr/local/mongodb/data
journal:
enabled: true
processManagement:
fork: true
net:
port: 27017
bindIp: 0.0.0.0 #配置文件中指定的dbpath和log要自己添加,不然会报错,执行命令
mkdir -p /usr/local/mongodb/data; mkdir -p /usr/local/mongodb/logs/;cd /usr/local/mongodb/logs/; touch mongodb.log ####第3步 加载配置文件运行
/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/bin/mongodb.conf ####第4步 添加环境变量,用于可以在任意目录下执行mongo命令
vim ~/.bash_profile #修改当前用户下的环境变量 PATH=$PATH:$HOME/bin:/usr/local/mongodb/bin
source ~/.bash_profile

安装完成后,在任意目录下使用命令 mongo 192.168.70.133:27017 (mongo命令会默认启动127.0.0.1:27017)启动mongodb,mongoDB使用的是javascript shell,我们简单测试一下,如果出现下边的界面表示安装成功了
这里简单使用一下mongoDB的shell来添加、删除数据库和collection:

2.安装Robomongo并连接数据库
mongoDB的GUI有MongoDB Compass、studio 3T等,这里使用的是Robomongo,下载地址:https://robomongo.org/,下载完成后一直Next安装即可,连接mongoDB效果如下,Robomongo是傻瓜式的用法,可以通过客户端添加collection,document,执行shell等,具体使用方法就不再详细介绍了。
· 
我们也可以通过shell脚本连接数据库,在Robomongo执行shell命令如下:

//连接远程数据库
var mongo=new Mongo("192.168.70.133:27017")
//找到数据库
var db=mongo.getDB("myDB");
//找到collecttion
var collection=db.getCollection("userinfo");
//查询colletion中所有数据
var list=collection.find().toArray();
//json形式打印结果
printjson(list);

3 mongoDB的shell
我们已经知道mongoDB是面向文档的nosql数据库,因为其无模式的特点,造成它的操作要比关系型数据库复杂一些,这里简单介绍一下mongoDB的CRUD操作。注意:从3.2版本开始,mongoDB添加了一些xxxOne()和xxxMany()方法,我们尽量使用这些新的方法。
1 添加(insert)
添加数据的指令是insert,使用方法如下:

insert方法的参数也可以是数组,用于批量添加数据,如下:
db.userinfos.insert([
{_id:1, name: "张三", age: 23},
{_id:2, name: "李四", age: 24}
]);
从3.2版本,mongoDB添加了insertOne和insertMany方法,分别用于单条插入和批量插入,用法很简单,如下:

//insertOne用于单条添加
db.userinfos.insertOne(
{_id:1, name: "张三", age: 23}
); //insertMany用于批量添加
db.userinfos.insertMany([
{_id:1, name: "张三", age: 23},
{_id:2, name: "李四", age: 24}
]);

2 查询(find)
mongoDB查询使用find函数,语法如下:

mongoDB使用find查询时,默认会返回主键_id,如果不想返回主键的话设置_id=0即可。mongoDB的查询语法是比较简单的,但是因为其无模式的特点,且field的值可以是对象和数组,造成mongoDB的运算符要比传统的关系型数据库多很多,如运算符$exists可用于查询field是否存在、$type用于判断filed的类型等等,这里汇总了一些常用的查询相关的运算符,有兴趣的小伙伴可以测试一下:
|
测试数据: ![]() db.userinfos.insertMany([ ![]() |
||||
| 类别 | 运算符 | 说明 | 实例 | 执行结果 |
|
比较运算符 |
$gt($gte) | 大于(大于等于) |
db.userinfos.find( ) |
查找age>25的文档的name 结果: [{ "_id" : 4, "name" : "赵六" }, { "_id" : 5, "name" : "田七" }] |
| $lt($lte) | 小于(小于等于) | db.userinfos.find(
{ age:{$lt:25}}, ) |
查找age<25的文档的name 结果: [ { "_id" : 1, "name" : "张三" }, { "_id" : 2, "name" : "李四" } ] |
|
| $eq | 等于 | db.userinfos.find(
{ age:{$eq:25}}, ) |
查询age=25的文档的name 结果: [ { "_id" : 3, "name" : "王五" } ] |
|
| $ne | 不等于 |
db.userinfos.find( |
查询age!=25的文档的name 结果: [{"_id" : 1,"name" : "张三"}, |
|
| $in | 包含 | db.userinfos.find(
{ age:{$in:[24,25]}}, |
查询age在[24,25]中的文档的name 结果: [ { "_id" : 2, "name" : "李四" }, { "_id" : 3, "name" : "王五" } ] |
|
| $nin | 不包含 | db.userinfos.find(
{ age:{$nin:[24,25]}}, |
查询age不在[24,25]中的文档的name 结果: [{"_id" : 1,"name" : "张三"}, |
|
| 逻辑运算符 | $and | 与 |
db.userinfos.find( {$and: [ {name:{$eq:'张三'}}, {age:{$eq:23}} ]}, {name:1} ) |
查询name='张三'且age=23的文档 结果: [ { "_id" : 1, "name" : "张三" } ] |
| $not |
非 |
db.userinfos.find(
{age:{$not:{$in:[23,24,25]}}}, |
查询age不在[23,24,24]中的文档 结果: [ { "_id" : 4, "name" : "赵六" }, { "_id" : 5, "name" : "田七" } ] |
|
| $or | 或 | db.userinfos.find(
{$or: [ {name:{$eq:'张三'}}, {age:{$eq:24}} ]}, {name:1} ) |
查询name='张三'或者age=24的文档 结果: [ { "_id" : 1, "name" : "张三" }, { "_id" : 2, "name" : "李四" } ] |
|
| $nor |
或的取反 |
db.userinfos.find(
{$nor: [ {name:{$eq:'张三'}}, {age:{$eq:24}} ]}, {name:1} ) |
上边栗子的取反操作 结果: [ {"_id" : 3,"name" : "王五"}, |
|
| 评估运算符 | $mod | 取余 |
db.userinfos.find( {age:{$mod:[10,3]}}, |
查询name%10=3的文档 结果: [ { "_id" : 1, "name" : "张三" } ] |
| $regex | 正则 |
db.userinfos.find( {name:{$regex:/^张/i}}, |
查询name以张开头的文档 结果: [ { "_id" : 1, "name" : "张三" } ] |
|
|
db.userinfos.find( {name:{$in:[/^张/,/四$/]}}, |
查询name以张开头或者以四结尾的文档 结果: [ { "_id" : 1, "name" : "张三" }, { "_id" : 2, "name" : "李四" } ] |
|||
| $where | where过滤 |
db.userinfos.find( ) |
查询名字为张三的记录 结果: [ { "_id" : 1, "name" : "张三" } ] 注意:where可以实现所有的过滤,但是效率不高。 这是因为where采用逐行判断而不使用索引 |
|
| $expr | 表达式过滤 |
db.userinfos.find( ) |
查询age<level的记录 结果: [ { "_id" : 3, "name" : "王五" }, { "_id" : 4, "name" : "赵六" } ] |
|
| 元素运算符 | $exists | field是否存在 |
db.userinfos.find( ) |
查询存在address字段的文档 结果: [ { "_id" : 5, "name" : "田七" }, { "_id" : 6, "name" : "周八" } ] |
| $type | field类型 |
db.userinfos.find( {name:{$type:'string'}}, {name:1} ) |
查询name为string的文档 结果: 所有文档都匹配 |
|
| 数组运算符 | $all | 包含所有元素才匹配成功 | db.userinfos.find(
{roles:{$all:['vip','gen']}}, {name:1} ) |
查询roles中包含vip和gen的文档 结果: [ { "_id" : 1, "name" : "张三" }, { "_id" : 3, "name" : "王五" } ] |
| $eleMatch | 只要有一个元素符合就匹配成功 | db.userinfos.find(
{roles:{$elemMatch:{ $eq: 'vip', $ne: 'gen' }}}, {name:1} ) |
查询roles中有元素等于vip,或有元素不等于gen的文档 结果: [{"_id" : 1,"name" : "张三"}, |
|
| $size | 元素个数相同的匹配成功 | db.userinfos.find(
{roles:{$size:2}}, {name:1} ) |
查询roles中有两个元素的文档 结果: [ { "_id" : 1, "name" : "张三" }, { "_id" : 3, "name" : "王五" } ] |
|
3 修改(update)
mongoDB修改documen使用的命令是update,语法如下:

mongoDB的update默认只修改一条document,如果想修改所有符合条件的documet的话,可以设置multi:true。upsert表示当没有符合过滤条件的文档时,就添加一条文档,并将修改的内容作为新增document的值。mongoDB的update功能比较丰富,如可以修改field的名字,删除field,以及对数组进行增删改。从3.2版本开始,mongoDB添加了updateOne()和updateMany()方法,用于修改单条或者多条数据,推荐使用新的方法,语法如下:

//将age<25的记录的level修改为50,只修改一条。updateOne相当于update设置multi:false
db.userinfos.updateOne(
{age:{$lt:25}},
{$set:{level:50}}
)
//将age<25的记录的level修改为50,所有符合条件的记录都修改。updateMany相当于update设置multi:true
db.userinfos.updateMany(
{age:{$lt:25}},
{$set:{level:50}}
)

这里汇总了mongoDB中关于update的相关运算符,有兴趣的小伙伴可以测试一下:
|
测试数据: ![]() db.userinfos.insertMany([ ![]() |
||||
| 值操作运算符 | $currentDate |
修改field值为当前时间, 如果field不存在则添加field |
db.userinfos.update( createtime:{$type:'timestamp'}} } |
将张三的createtime字段值修改为当前时间 格式为时间戳("createtime" : Timestamp(1560663270, 1)) 补充:如果不设置$type,默认的格式为date 格式为date("createtime" : ISODate("2019-06-16T05:38:21.119Z"))
|
| $set |
修改值 |
db.userinfos.update( {level:20} } |
将张三的level修改为20。如果要修改的field不存在,不会添加新的field。 | |
| $setOnInsert |
只有在新增document时进行赋值, 一定要设置upsert:true |
db.userinfos.update( {level:30} }, |
因为已经有name=张三的document,所以不做任何操作 | |
|
db.userinfos.update( |
添加一个name=吴九的document,并设置level为30 | |||
| $inc | 自增 |
db.userinfos.update( {age:10} } |
张三的age自增10,age修改为23+10=33 | |
| $mul | 自乘 |
db.userinfos.update( {age:2} } |
张三的age自乘2,age修改为23*2=46 | |
| $min | 取小 |
db.userinfos.update( {age:13} } |
张三的age取小值,因为23>13,所以修改age为13。如果修改的值比23大,那么不做操作。 | |
| $max | 取大 |
db.userinfos.update( {age:33} } |
张三的age取大值,因为23<33,所以修改age为33。如果修改的值比23小,那么不做操作。 | |
| 字段操作运算符 | $rename | 修改filed的名字 | db.userinfos.update(
{name:'张三'}, {age:'年龄'} } |
将张三的age字段名改成年龄,值不变,年龄=23 |
| $unset | 删除field | db.userinfos.update(
{name:'张三'}, {level:''} } |
将张三的level字段删除 | |
数组相关的update运算符:
|
测试数据: db.students.insertMany( |
||||
| 数组运算符 | $ | 单个占位符 |
db.students.updateOne( |
修改_id=1的文档graders中第一个值为80的元素,值改成82 结果: [{ "_id" : 1, "grades" : [ 85, 82, 80 ] }, |
| $[] | 所有元素占位符 |
db.students.updateOne( |
修改_id=1的文档graders中所有元素,值改成100 结果: [{ "_id" : 1, "grades" : [ 100, 100, 100 ] }, |
|
| $[<identifier>] | 符合arrayFilter过滤条件的元素占位符 |
db.students.updateOne( |
修改_id=2的文档graders中大于等于90的元素,值改成100 结果: [{ "_id" : 1, "grades" : [ 85, 82, 80 ] }, |
|
| $push | 添加元素 |
db.students.updateOne( |
在_id=1的文档graders中添加元素 结果: [{ "_id" : 1, "grades" : [ 85, 80, 80 ,98 ] }, |
|
| $addToSet | 添加不存在的元素,如果元素已经存在则无操作 | db.students.updateOne( { _id: 1 }, { $addToSet: { "grades" : 100 } } ) |
在_id=1的文档graders中添加元素 结果: [{ "_id" : 1, "grades" : [ 85, 80, 80 ,98,100 ] }, 补充:如果添加的元素是85,因为85已经存在,所以不执行操作 |
|
| $pop | 弹出(移除)元素 |
db.students.updateOne( |
移除最后一个元素 结果: [{ "_id" : 1, "grades" : [ 85, 80 ] }, 补充:如果{ $pop: { "grades" : -1 } }表示从前边弹出,移除第一个元素 |
|
| $pullAll | 根据值移除数组中的元素 |
db.students.update( |
移除_id=2的文档的graders中值为88,90的所有元素 结果: [{ "_id" : 1, "grades" : [ 85, 80, 80 ] }, |
|
| $pull | 移除符合条件的元素 |
db.students.update( |
移除_id=2的文档的graders中大于90的所有元素 结果: [{ "_id" : 1, "grades" : [ 85, 80, 80 ] }, |
|
|
数组批量添加 相关运算符 |
$each | 和$push,$addToSet配合使用,用于批量添加元素 |
db.students.update( {grades:{$each:[99,100]}} } ) |
在_id=1的文档graders中添加元素[99,100] 结果: [{ "_id" : 1, "grades" : [ 85, 80, 80 ,99,100 ] }, |
| $slice | 和$push,$each配合使用,用于限制元素个数 |
db.students.update( {grades:{$each:[99,100],$slice:4}} } |
在_id=1的文档graders中添加元素[99,100]
结果: [{ "_id" : 1, "grades" : [ 85, 80, 80 ,99] }, 如果使用$slice:-4,则保留后4个元素 |
|
| $sort | 和$push,$each配合使用,在添加元素后进行排序 |
db.students.update( {grades:{$each:[70,100],$sort:1}} } |
在_id=1的文档graders中添加元素[99,100],并排序
结果: [{ "_id" : 1, "grades" : [70,80,80,85,100]}, 如果使用$sort:-1,则倒序排序 |
|
| $position | 和$push,$each配合使用,指定插入元素的位置 |
db.students.update( {grades:{$each:[70,100],$position:1}} } |
在_id=1的文档graders中,从索引1开始插入元素[99,100]
结果: [{ "_id" : 1, "grades" : [85,70,100,80,80]}, |
|
4.删除(remove/delete)
在3.2以前的版本中,mongoDB使用remove方法来删除文档,用法如下:

从3.2版本开始,提供了deleteOne()和deleteMany()方法,分别用于删除单条和多条document,语法如下:
//删除单条document,功能类似于remove设置justOne:true
db.userinfos.deleteOne({age:{$gt:25}})
//删除所有符合条件的document,功能类似于remove设置justOne:false
db.userinfos.deleteMany({age:{$gt:25}})
本篇是mongoDB的第一篇,简单介绍了mongoDB的安装方法,通过js shell进行mongoDB的CRUD操作,后续会逐步介绍mongoDB的索引、数据聚合、GridFS和C#驱动,以及副本集和sharing集群搭建。如果本文由错误的地方,希望大家可以指出,我会及时修改,谢谢。
mongoDB(一)——mongoDB安装部署和常用shell命令的更多相关文章
- 快速掌握mongoDB(一)——mongoDB安装部署和常用shell命令
1.mongoDB简介 mongoDB 是由C++语言编写的,是一种分布式的面向文档存储的开源nosql数据库.nosql是Not Only SQL的缩写,是对不同于传统的关系型数据库的数据库管理系统 ...
- HBase 安装与配置及常用Shell命令
HBase 安装与配置 首要配置 配置时间同步(所有节点上执行) yum -y install chrony vi /etc/chrony.conf #写入(7版本用server:8版本用pool): ...
- Windows常用shell命令大全
Windows常用shell命令大全 基于鼠标操作的后果就是OS界面外观发生改变, 就得多花学习成本.更主要的是基于界面引导Path与命令行直达速度是难以比拟的.另外Geek很大一部分是键盘控,而非鼠 ...
- Ubuntu常用shell命令
目录 ls cd mkdir mv cp scp rm df du chmod chown chgrp head tail screen apt-get Ubuntu常用shell命令 Ubuntu作 ...
- Windows常用shell命令大全(转)
[Windows常用shell命令大全] 基于鼠标操作的后果就是OS界面外观发生改变, 就得多花学习成本.更主要的是基于界面引导Path与命令行直达速度是难以比拟的.另外Geek很大一部分是键盘控,而 ...
- Linux Shell常用shell命令
Linux Shell常用shell命令 一.文件.目录操作命令 1.ls命令 功能:显示文件和目录的信息 ls 以默认方式显示当前目录文件列表 ls -a 显示所有文件包括隐藏文件 ls -l 显示 ...
- 原 HBase 常用Shell命令
HBase 常用Shell命令 1.进入hbase shell console $HBASE_HOME/bin/hbase shell 如果有kerberos认证,需要事先使用相应的keytab进行一 ...
- Ubuntu14.04下Mongodb官网安装部署步骤(图文详解)(博主推荐)
不多说,直接上干货! 在这篇博客里,我采用了非官网的安装步骤,来进行安装.走了弯路,同时,也是不建议.因为在大数据领域和实际生产里,还是要走正规的为好. Ubuntu14.04下Mongodb(离线安 ...
- Ubuntu16.04下Mongodb官网安装部署步骤(图文详解)(博主推荐)
不多说,直接上干货! 在这篇博客里,我采用了非官网的安装步骤,来进行安装.走了弯路,同时,也是不建议.因为在大数据领域和实际生产里,还是要走正规的为好. Ubuntu16.04下Mongodb(离线安 ...
随机推荐
- JDK的sql设计不合理导致的驱动类初始化死锁问题
问题描述 当我们一个系统既需要mysql驱动,也需要oracle驱动的时候,在并发加载初始化这些驱动类的过程中产生死锁的可能性非常大,下面是一个模拟的例子,对于Thread2的实现其实是jdk里jav ...
- Python第六章-函数05-迭代器&生成器
python作为一个既面向对象,又支持函数式编程的语言,函数的使用方面有很多特点. 比如:闭包,装饰器,迭代器等 函数的高级应用 容器:生活中常见的容器有哪些?袋子,盆子,水杯,书包,铅笔盒... 容 ...
- VBScript - 动态 Array 实现方法大全!
记录一些方法,关于 VBScript 中,动态 Array 的实现 ,也适用于 VBA, 很久以前,写 VBA 的时候,就觉得使用 Array 很不方便,因为大小固定, 当时想的是,要是 Array ...
- Jmeter 注册用户获取登录token值
1. 打开jemeter,新建一个测试计划,>线程组 >新建一个 登录的 Http 请求. 2.填上相应的值 3.新建一个消息头管理器> content-Type applicat ...
- 我遇到的一个ClassNotFoundException问题
近期,使用socket进行进程间Object通信,但是总是报ClassNotFoundException错误. 查找了很多原因,均没有解决. 通过写入文件,查看Object发送的消息内容到底是何种格式 ...
- 【Jenkins】使用 Jenkins REST API 配合清华大学镜像站更新 Jenkins 插件
自从去年用上了 Jenkins 进行 CI/CD 之后,工作效率高了不少,摸鱼的时间更多了.不过 Jenkins 好是好,但在功夫网的影响下,插件就是经常更新不成功的,就像下面这样子: 查了不少资料, ...
- Three.js制作一个基本的飞行3D场景【源代码】
原文链接:https://tympanus.net/codrops/2016/04/26/the-aviator-animating-basic-3d-scene-threejs/ 源代码下载链接:h ...
- Linux命令后面加 & 的作用
在命令的后面加一个 & 的作用是,将这个任务放到后台执行.看下面的例子. 输入gedit回车,可以看到,打开了Linux的文本编辑器,但是命令窗口执行不了其他命令了,只有退出文本编辑器才能继续 ...
- 关于$f(x)=\int_0^x\left|\sin\frac1t\right|\text dt$求导的问题
首先,我们考虑\(f(x)\)在\(\mathbb R\)上都是定义的.根据定义,显然有\(f(0)=0\):其次,对于\(x\neq0\),不妨先设\(x\gt0\),则有在\(t\rightarr ...
- 机器学习4- 多元线性回归+Python实现
目录 1 多元线性回归 2 多元线性回归的Python实现 2.1 手动实现 2.1.1 导入必要模块 2.1.2 加载数据 2.1.3 计算系数 2.1.4 预测 2.2 使用 sklearn 1 ...