Mongodb
- 定义
MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案,它是一个NoSQL。
NoSQL:非关系型数据库 NoSQL = Not Only SQL
2. 关系型数据库和非关系型数据库的区别
关系型数据库:由行和列组成的二维表,有模式的,表是有关系的(连接查询,外键)。
非关系型数据库:无模式的,表之间无关系,且非关系型数据库存储的格式各不相同。
3. HBase和Mongodb的区别
HBase: 面向列族存储的,KeyValue
Mongodb: 文档性数据库,BSON
SQL Mongodb
DataBase DataBase 数据库
Table Collection 数据表/集合
row/record Document 记录/文档
column/field field 列/字段
primary key primary key 主键
index index 索引
table joins 无
4. 安装MongoDB
4.1、上传mongodb_rpms_3.6.2.tar.gz
4.2、解压
[hadoop@hadoop01 installPkg]$ tar -zxvf mongodb_rpms_3.6.2.tar.gz
4.3、因为需要将mongodb安装成系统服务,开机启动。此时需要root权限
同时rpm默认安装在/usr/bin下,而/usr/bin的权限是root
[hadoop@hadoop01 mongodb_3.6.2]$ sudo rpm -ivh *.rpm
4.4、配置文件在/etc/
[hadoop@hadoop10 bin]$ cd /etc/
[hadoop@hadoop10 etc]$ ll | grep mongo
-rw-r--r--. 1 root root 804 Jan 11 2018 mongod.conf
[hadoop@hadoop10 etc]$ sudo vim mongod.conf
# network interfaces
net:
port: 27017
bindIp: hadoop01 #空格不能省略
4.5、启动服务
[hadoop@hadoop10 etc]$ sudo service mongod start
[hadoop@hadoop10 etc]$ sudo chkconfig mongod on
4.6、使用客户端(mongo shell)连接
[hadoop@hadoop01 etc]$ mongo --help
[hadoop@hadoop10 etc]$ mongo --host hadoop01
5. MongoDB是一个文档数据库
MongoDB中的记录是一个文档Document,它是由字段和值对组成的数据结构。MongoDB文档类似于JSON对象。字段的值可能包括其他文档、数组和文档数组。
Databases and Collections:
MongoDB在集合中存储BSON文档,即数据记录;在数据库中的集合中。
6.Document结构:
{
field1: value1,
field2: value2,
field3: value3,
...
fieldN: valueN
}
字段名是字符串。文档的字段有以下的限制:
1、字段name为 _id保留作主键;它的值在集合中必须是唯一的,不可变的,并且可以是数组以外的任何类型。
2、字段名不能包含空字符。
3、顶级字段名不能以美元符号($)开头。
MongoDB使用点符号来访问数组的元素和嵌入文档的字段。
"<array>.<index>"
"<embedded document>.<field>"
7. _id字段:
7.1、在MongoDB中,存储在集合中的每个文档都需要一个惟一的_id字段作为主键。如果插入的文档省略了_id字段,MongoDB驱动程序会自动为_id字段生成一个ObjectId。
7.2、_id字段具有以下行为和约束
默认情况下,MongoDB在创建集合时在_id字段上创建一个唯一的索引。
_id字段可以包含任何BSON数据类型的值,除了数组。
为了确保复制功能正常,不要在_id字段中存储BSON正则表达式类型的值。
8. BSON数据类型:
Type Number Alias(笔名) Notes(备注)
Double 1 “double”
String 2 “string”
Object 3 “object”
Array 4 “array”
Binary data 5 “binData”
ObjectId 7 “objectId”
Boolean 8 “bool”
Date 9 “date”
Null 10 “null”
Regular Expression 11 “regex”
JavaScript 13 “javascript”
JavaScript (with scope) 15 “javascriptWithScope”
32-bit integer 16 “int”
Timestamp 17 “timestamp”
64-bit integer 18 “long”
Decimal128 19 “decimal” New in version 3.4.
Min key -1 “minKey”
Max key 127 “maxKey”
9. ObjectId类型:
objectid很小,可能是惟一的,生成速度快,并且有序。ObjectId值的长度为12字节,包括:
一个4字节的时间戳值,表示ObjectId的创建,以Unix时代以来的秒为单位
一个5字节的随机值
一个3字节递增计数器,初始化为一个随机值
611b6745202d38df36b125b7
在mongo shell中,您可以使用ObjectId. getTimestamp()方法访问ObjectId的创建时间。
> var o = ObjectId()
> o.getTimestamp()
ISODate("2021-08-17T03:14:43Z")
10. 操作数据库:
10.1、查看当前的数据库
> db
test
10.2、查看所有的数据库
> show databases
admin 0.000GB
config 0.000GB
local 0.000GB
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
注意:如果数据库中没有数据,那么数据库不显示
10.3、切换数据库
> use mall
switched to db mall
注意:mongodb中use切换数据库,如果该库不存在,也可以切换,当插入数据的时候
该库就会创建。所以mongodb中不需要手动创建数据库。
10.4、查看数据库的状态
> db.stats()
{
"db" : "mall",
"collections" : 0,
"views" : 0,
"objects" : 0,
"avgObjSize" : 0,
"dataSize" : 0,
"storageSize" : 0,
"numExtents" : 0,
"indexes" : 0,
"indexSize" : 0,
"fileSize" : 0,
"fsUsedSize" : 0,
"fsTotalSize" : 0,
"ok" : 1
}
10.5、终端退出连接
> exit
或
ctrl+c
10.6、删除数据库
> db.dropDatabase()
删除当前指向的数据库
如果数据库不存在,则不做任何操作
11. 操作集合
-------------------操作集合----------------
11.1 创建集合:
db.createCollection(name, options)
db.createCollection(<name>, { capped: <boolean>,
size: <number> } )
name: 集合的名称
capped:可选的。若要创建capped集合,请指定true。如果指定为true,还必须在size字段中设置最大大小。
size: 可选的。为有上限的集合指定以字节为单位的最大大小。一旦有上限的集合达到其最大大小,MongoDB就会删除旧文档,为新文档腾出空间。size字段对于有上限的集合是必需的,对于其他集合则被忽略。
> db.createCollection("student")
{ "ok" : 1 }
在mongodb使用过程中,是不需要创建集合
在对集合插入数据的时候,如果该集合不存在会自动创建
11.2 查看当前数据库中的集合:
> show tables
student
teacher
> show collections
student
teacher
11.3 删除集合:
db.集合.drop()
> db.teacher.drop()
true
11.4 插入数据:
db.collection.insertOne(
<document>,
{
writeConcern: <document>
}
)
collection需要换成具体的集合名称
document就是插入的数据
writeConcern写数据的安全级别,是可选的,有默认值
> db.student.insertOne({name:"zhangsan",age:20})
{
"acknowledged" : true,
"insertedId" : ObjectId("611b542f6e4bbb2c2327f11f")
}
11.5 插入数据手动指定_id
> db.student.insertOne({_id:10001,name:"李四",sex:"男"})
{ "acknowledged" : true, "insertedId" : 10001 }
> db.student.insertOne({_id:10001,name:"wangwu",sex:"男"})
WriteError({
"index" : 0,
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: test.student index: _id_ dup key: { : 10001.0 }",
"op" : {
"_id" : 10001,
"name" : "wangwu",
"sex" : "男"
}
})
duplicate key error: 重复键错误
11.6 复合主键:
_id的类型是一个document,就是复合主键
> db.student.insertOne(
{
_id:{
id:100,name:'id',info:"主键"
},
name:"hanmeimei",
age:22
}
)
{
"acknowledged" : true,
"insertedId" : {
"id" : 100,
"name" : "id",
"info" : "主键"
}
}
> db.student.insertOne(
{
_id:{
name:'id',info:"主键",id:100
},
name:"lucy",
age:23
}
)
{
"acknowledged" : true,
"insertedId" : {
"name" : "id",
"info" : "主键",
"id" : 100
}
}
注意:复合主键只有当kv内容一样,顺序一样才是相同的主键
11.7 db.collection.insertMany语法:
db.collection.insertMany(
[ <document 1> , <document 2>, ... ],
{
writeConcern: <document>,
ordered: <boolean>
}
)
ordered:可选的。一个布尔值,指定mongod实例应该执行有序插入还是无序插入。默认值为true。
> db.student.insertMany(
[
{_id:1001,name:'lilei',age:20,sex:'male'},
{_id:1002,name:'lily',address:'chengdu',hobbies:['music','boyfriend','eat']}
]
)
{ "acknowledged" : true, "insertedIds" : [ 1001, 1002 ] }
> db.student.insertMany(
[
{_id:1001,name:'lilei',age:20,sex:'male'},
{_id:1003,name:'hanmeimei',address:'chengdu'}
]
)
BulkWriteError({
"writeErrors" : [
{
"index" : 0,
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: test.student index: _id_ dup key: { : 1001.0 }",
"op" : {
"_id" : 1001,
"name" : "lilei",
"age" : 20,
"sex" : "male"
}
}
],
"writeConcernErrors" : [ ],
"nInserted" : 0,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})
"nInserted" : 0 说明数据没有插入成功
因为以上数据采用的是有序插入,有序插入就是后面的数据需要等待前面数据插入成功,如果前面的数据插入失败,后面的数据也无法插入
> db.student.insertMany(
[
{_id:1001,name:'lilei',age:20,sex:'male'},
{_id:1003,name:'hanmeimei',address:'chengdu'}
],
{ordered:false}
)
BulkWriteError({
"writeErrors" : [
{
"index" : 0,
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: test.student index: _id_ dup key: { : 1001.0 }",
"op" : {
"_id" : 1001,
"name" : "lilei",
"age" : 20,
"sex" : "male"
}
}
],
"writeConcernErrors" : [ ],
"nInserted" : 1,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})
"nInserted" : 1 表示成功插入一条
因为使用了无序插入,前面数据的插入不影响后面数据的插入
11.8 db.collection.save语法:
db.collection.save(
<document>,
{
writeConcern: <document>
}
)
> db.student.save(
{name:'bill',age:22}
)
如果文档不包含_id字段,则save()方法调用insert()方法。在操作期间,mongo shell将创建一个ObjectId并将其分配给_id字段。
如果数据的_id已经存在就是替换现有的文档
> db.student.save(
{"_id" : ObjectId("611b6ab90ad895f9d53f39d9"),name:'bill01',age:22}
)
12.查询数据
----------------查询数据-------------
12.1 db.collection.find(query, projection)
query:document类型,可选的。使用查询操作符指定选择筛选器。若要返回集合中的所有文档,请省略此参数或传递一个空文档({})。
projection:document类型,可选的。指定与查询筛选器匹配的文档中要返回的字段。若要返回匹配文档中的所有字段,请省略此参数。
根据条件查询语法:
{
<field1>: <value1>,
<field2>: { <operator>: <value> },
...
}
注意: <field1>: <value1> 表示等于
12.2 查询操作符:
Query Selectors - 比较:
$eq Matches values that are equal to a specified value.(相等)
$gt Matches values that are greater than a specified value.(大于)
$gte Matches values that are greater than or equal to a specified value.(大于等于)
$in Matches any of the values specified in an array.(包含)
$lt Matches values that are less than a specified value.(小于)
$lte Matches values that are less than or equal to a specified value.(小于等于)
$ne Matches all values that are not equal to a specified value.(不等于)
$nin Matches none of the values specified in an array.(不包含)
12.2.1、查询age是22的student信息
> db.student.find({
age:22
})
{ "_id" : ObjectId("611b6ab90ad895f9d53f39d9"), "name" : "bill01", "age" : 22 }
{ "_id" : ObjectId("611b6cb00ad895f9d53f39da"), "name" : "andy", "age" : 22, "sex" : "female" }
12.2.2、查询age大于22的student信息
> db.student.find({
age:{$gt:22}
})
{ "_id" : ObjectId("611b6cb00ad895f9d53f39db"), "name" : "rose", "age" : 23, "sex" : "female" }
12.2.3、查询name是hanmeimei的student信息
> db.student.find({
name:'hanmeimei'
})
{ "_id" : 1003, "name" : "hanmeimei", "address" : "chengdu" }
模拟数据:
db.student.insert(
[
{_id:{id:1001,"address":"shanghai"},name:"lisi",age:22},
{_id:{id:1002,address:"beijing"},name:"tom",age:21}
]
)
12.2.4、查询主键中address是shanghai的student信息
key不是一个字段的时候,需要使用引号
> db.student.find({
'_id.address':'shanghai'
})
{ "_id" : { "id" : 1001, "address" : "shanghai" }, "name" : "lisi", "age" : 22 }
12.2.5、查询name是lisi,rose,hanmeimei的student信息
> db.student.find({
name:{$in:['lisi','rose','hanmeimei']}
})
{ "_id" : 1003, "name" : "hanmeimei", "address" : "chengdu" }
{ "_id" : ObjectId("611b6cb00ad895f9d53f39db"), "name" : "rose", "age" : 23, "sex" : "female" }
{ "_id" : { "id" : 1001, "address" : "shanghai" }, "name" : "lisi", "age" : 22 }
模拟数据:
db.student.insert({
id:1003,age:20,address:'未知'
})
12.2.6、查询name不是lisi,rose,hanmeimei的student信息
> db.student.find({
name:{$nin:['lisi','rose','hanmeimei']}
})
注意:$nin会返回值不在数组中的信息和数据中没有该字段的信息
13.Query Selectors - 逻辑:
Name Description
$and 条件同时成立
$not 非(反转查询表达式的效果,并返回与查询表达式不匹配的文档。)
$nor 一个成立的取反。
$or 或,条件只要有一个成立即可
逻辑操作,条件至少有两个,所以$or后面应该是数组
13.1、查询age是22岁的女娃
> db.student.find({
age:22,sex:'female'
})
{ "_id" : ObjectId("611b6cb00ad895f9d53f39da"), "name" : "andy", "age" : 22, "sex" : "female" }
13.2、查询age是22岁的女娃
$and 条件同时成立,条件至少有两个,所以$and后面应该是数组
> db.student.find({
$and:[
{age:22},
{sex:'female'}
]
})
{ "_id" : ObjectId("611b6cb00ad895f9d53f39da"), "name" : "andy", "age" : 22, "sex" : "female" }
结论:当$and后面条件的字段不相同的时候,$and可以省略
13.3、查询age大于20小于23岁的女娃
> db.student.find({
$and:[
{age:{$gt:20}},
{age:{$lt:23}},
{sex:'female'}
]
})
{ "_id" : ObjectId("611b6cb00ad895f9d53f39da"), "name" : "andy", "age" : 22, "sex" : "female" }
注意:如果$and连接的是相同的字段,可以省略$and,简写成:
> db.student.find({
age:{$gt:20,$lt:23},sex:'female'
})
13.4、查询姓名是andy或者年龄等于23的学生信息
$or 条件至少有两个,所以$or后面应该是数组
> db.student.find({
$or:[
{name:'andy'},
{age:23}
]
})
{ "_id" : ObjectId("611b6cb00ad895f9d53f39da"), "name" : "andy", "age" : 22, "sex" : "female" }
{ "_id" : ObjectId("611b6cb00ad895f9d53f39db"), "name" : "rose", "age" : 23, "sex" : "female" }
注意:字段不同的时候$or不能省略
13.5、查询姓名是andy或者tom学生信息
> db.student.find({
$or:[
{name:'andy'},
{name:'tom'}
]
})
{ "_id" : ObjectId("611b6cb00ad895f9d53f39da"), "name" : "andy", "age" : 22, "sex" : "female" }
{ "_id" : { "id" : 1002, "address" : "beijing" }, "name" : "tom", "age" : 21 }
> db.student.find({
name:{$in:['andy','tom']}
})
{ "_id" : ObjectId("611b6cb00ad895f9d53f39da"), "name" : "andy", "age" : 22, "sex" : "female" }
{ "_id" : { "id" : 1002, "address" : "beijing" }, "name" : "tom", "age" : 21 }
注意:如果$or后面的字段一样,效果和$in是一样的
13.6、查询年龄不小于22岁的学生信息
> db.student.find({
age:{$gte:22}
})
{ "_id" : ObjectId("611b6ab90ad895f9d53f39d9"), "name" : "bill01", "age" : 22 }
{ "_id" : ObjectId("611b6cb00ad895f9d53f39da"), "name" : "andy", "age" : 22, "sex" : "female" }
{ "_id" : ObjectId("611b6cb00ad895f9d53f39db"), "name" : "rose", "age" : 23, "sex" : "female" }
{ "_id" : { "id" : 1001, "address" : "shanghai" }, "name" : "lisi", "age" : 22 }
> db.student.find({
age:{$not:{$lt:22}}
})
13.7、查询姓名不是andy和tom,年龄不是23的学生信息
$nor 表示的是都不满足条件
> db.student.find({
$nor:[
{name:{$in:['andy','tom']}},
{age:23}
]
})
注意:$nor和前面的$not,$nin,$ne 一样,都会匹配出没有该字段的数据
官方文档:https://docs.mongodb.com
750ba2295631 8 月前
06d749896ac2 8 月前