个人blog-1: 拾忆生活
个人blog-2: 极简-拾忆生活
欢迎大家来踩,同步更新
简介
1.NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL"。非关系型的数据存储库
2.分布式系统是建立在网络之上的软件系统,是一个基于分布式文件存储的开源数据库系统。
3.文档存储一般用类似json的格式存储,存储的内容是文档型的.这样也就有机会对某些字段建立索引,实现关系数据库的某些功能。
4.MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。
2.MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。
{
name:"Lewis", <--fields:value
age:20, <--fields:value
group:["news","sports"] <--fields:value
}
配置:
1.创建数据目录
D:\mongoDB\data\db
2.运行 MongoDB 服务器
D:\mongoDB\bin
mongod.exe --dbpath "D:\MongoDB\data\db"
3.在浏览器输入http://localhost:27017 (27017是mongodb的端口号)查看,若显示如下,则表示连接成功。如果不成功,可以查看端口是否被占用。
4.添加你安装MongoDB的bin目录到环境变量中的path
D:\MongoDB\bin
5.一定不要关闭,保持MongoDB开启连接MongoDB
D:\mongoDB\bin>
mongo
将MongoDB设置为系统服务,可以自动在后台启动
1.创建D:\mongoDB\data\log
2.创建D:\mongoDB,添加配置文件mongod.cfg
systemLog:
destination: file
path: D:\mongoDB\data\log\mongod.log
storage:
dbPath: D:\mongoDB\data\db
3.管理员打开cmd
sc.exe create MongoDB binPath= "\"D:\mongoDB\bin\mongod.exe\" --service --config=\"D:\mongoDB\mongod.cfg\"" DisplayName= "MongoDB" start= "auto"
介 绍 \color{red}介绍 介绍
- 数据库的服务器
- 用来保存数据
- mongod用来启动服务器
- 数据库的客户端
- 用来操作服务器,对数据增删查改
- mongo用来启动客户端
设 置 系 统 服 务 前 的 打 开 方 式 \color{red}设置系统服务前的打开方式 设置系统服务前的打开方式
1.在一个cmd中打开:D:\mongoDB\bin
指定数据库路径和其使用的端口号
输入:mongod.exe --dbpath "D:\MongoDB\data\db" --port 27017
2.在另一个cmd中打开
输入:mongo
设 置 系 统 服 务 后 的 打 开 方 式 \color{red}设置系统服务后的打开方式 设置系统服务后的打开方式
1.启动MongoDB服务(管理员身份cmd)
net start MongoDB
2.关闭MongoDB服务
net stop MongoDB
3.移除 MongoDB 服务
C:\mongodb\bin\mongod.exe --remove
4.在另一个cmd中打开
输入:mongo
基
本
概
念
\color{red}基本概念
基本概念
数据库(database),不需要手动创建,数据库中包含集合
集合(collection),不需要手动创建,集合中包含文档
文档(document)
n a v i c a t f o r M o n g o D B \color{red}navicat for MongoDB navicatforMongoDB
F6 打开一个mongodb命令行窗口
ctrl+r 运行查询窗口的mongodb语句
ctrl+/ 注释sql语句
ctrl+shift +/ 解除注释
连 接 \color{red}连接 连接
mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]
mongodb://
固定格式
username:password@
可选登录用户名密码
host
连接服务器的地址。
如果要连接复制集,请指定多个主机地址。
portX
可选端口,如果不填,默认为27017
/database
如果指定username:password@,连接并验证登陆指定数据库。
若不指定,默认打开 test 数据库。
?options
是连接选项。如果不使用/database,则前面需要加上/。
所有连接选项都是键值对name=value,键值对之间通过&或;(分号)隔开
举例:
1.使用用户名和密码连接登陆到本地指定数据库服务器
mongodb://admin:123456@localhost/test
2.连接 replica pair, 服务器1为example1.com服务器2为example2。
mongodb://example1.com:27017,example2.com:27017
3.连接 replica set 三台服务器, 写入操作应用在主服务器 并且分布查询到从服务器。
mongodb://host1,host2,host3/?slaveOk=true
4.直接连接第一个服务器,无论是replica set一部分或者主服务器或者从服务器。
mongodb://host1,host2,host3/?connect=direct;slaveOk=true
5.安全模式连接到localhost:
mongodb://localhost/?safe=true
以安全模式连接到replica set,并且等待至少两个复制服务器成功写入,超时时间设置为2秒。
mongodb://host1,host2,host3/?safe=true;w=2;wtimeoutMS=2000
使 用 数 据 库 \color{red}使用数据库 使用数据库
1.显示当前的数据库名称
> db
test
2.显示当前服务器下所有数据库database
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
3.如果test数据库不存在,则创建test数据库;
如果test已存在,则切换到test数据库。
> use test
4.删除当前数据库
>db.dropDatabase()
使 用 集 合 \color{red}使用集合 使用集合
1.显示当前数据库下集合collections
> show collections
2.当前数据库自动创建stu集合
db.stu.insert({"name" : "菜鸟教程"})
3.当前数据库手动创建stu集合
> db.createCollection("stu") # 先创建集合,类似数据库中的表
4.当前数据库创建固定stu集合,整个集合空间大小 6142800 KB, 文档最大个数为 10000 个
> db.createCollection("stu", { capped:true, autoIndexId:true, size:6142800, max:10000 } )
5.删除当前数据库指定的stu集合
>db.stu.drop()
C R U D 使 用 \color{red}CRUD使用 CRUD使用
先明确使用数据库
db (加入返回test,则当前在test数据库)
1.插入文档
注:
向集合中添加文档,如果文档没有指定_id属性,会自动添加
{"_id":objectId(xxxxxx),···},作为文档的唯一标识
根据时间戳和机器码来生成
自己指定id:
db.stu.insert({_id:"id123",name:"zhangsan"});
查询id:
ObjectId();
1.插入json格式文档
>db.stu.insert({
title: 'MongoDB',
description: 'MongoDB 是一个 Nosql 数据库',
by: '教程',
url: 'https://www.baidu.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
})
2.插入的文档定义为变量
> document=({title: 'MongoDB 教程',
description: 'MongoDB 是一个 Nosql 数据库',
by: '菜鸟教程',
url: 'http://www.runoob.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
});
db.stu.insert(document);
3.插入方法
db.collection.insertOne(): 向指定集合中插入一条文档数据
db.collection.insertMany(): 向指定集合中插入多条文档数据
# 插入单条数据
> var document = db.collection.insertOne({"a": 3})
返回:document
{
"acknowledged" : true,
"insertedId" : ObjectId("571a218011a82a1d94c02333")
}
# 插入多条数据
> var res = db.collection.insertMany([{"b": 3}, {'c': 4}])
返回:res
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("571a22a911a82a1d94c02337"),
ObjectId("571a22a911a82a1d94c02338")
]
}
极
重
要
的
实
例
\color{red}极重要的实例
极重要的实例
插入20000条记录
1.(执行20000次)该方法7.2s
for(i=1;1<=20000;i++){
db.stu.insert({num:i});
}
2.(执行一次,添加到数组)该方法0.4s
var arr = [];
for(var i=1 ; i<=20000 ; i++){
arr.push({num:i});
}
db.numbers.insert(arr);
2.查询
find查询函数的属性
注:
find() 返回的是一个数组
findOne() 返回的是第一个文档对象
findMany()
所以
-
1.返回所有文档对象
- db.stu.find({});
- db.col.find({},{“title”:1,_id:0})
第 一 个 放 w h e r e 条 件 , 为 空 表 示 返 回 集 合 中 所 有 文 档 \color{red}第一个 {} 放 where 条件,为空表示返回集合中所有文档 第一个放where条件,为空表示返回集合中所有文档
第 二 个 指 定 那 些 列 显 示 和 不 显 示 ( 0 表 示 不 显 示 , 1 表 示 显 示 ) \color{red}第二个 {} 指定那些列显示和不显示 (0表示不显示,1表示显示) 第二个指定那些列显示和不显示(0表示不显示,1表示显示)
-
2.返回文档对象有几个
- db.stu.find({}).count();
-
3.返回符合条件的第一个文档对象
- db.stu.find({name:‘a’})[0];
-
4.返回符合条件的第一个文档对象的name属性
- db.stu.findOne({age:‘a’}).name;
-
5.查询stu集合中的第一个文档对象
- db.stu.findOne()
-
6.查询stu集合中前5条数据
- db.stu.find().limit(5)
-
7.查询stu集合中跳过前5条后的数据
s k i p ( ) 方 法 来 跳 过 指 定 数 量 的 数 据 , 默 认 参 数 为 0 \color{red}skip()方法来跳过指定数量的数据,默认参数为0 skip()方法来跳过指定数量的数据,默认参数为0- db.stu.find().skip(5)
-
8.查询stu集合中的全部数据,并按name属性正序排列 注:1:正序 -1: 倒序
- db.stu.find().sort({name:1})
-
pretty() 方法以格式化的方式来显示所有文档
- db.stu.find().pretty()
注:limit和skip可用于分页
skip(), limilt(), sort()三个放在一起执行的时候,执行的顺序是
先
s
o
r
t
(
)
,
然
后
s
k
i
p
(
)
,
最
后
l
i
m
i
t
(
)
\color{red}先 sort(), 然后 skip(),最后 limit()
先sort(),然后skip(),最后limit()
查看第11条到20条的记录
db.stu.find().skip(10).limit(10);
find查询函数
- 1.查询stu集合中所有的数据
- db.stu.find()
- 2.查询stu集合中name='a’的数据
- db.stu.find({name:‘a’})
- 3.查询stu集合中name='a’的数据
- db.stu.find({name:{$eq:‘a’}})
- 4.查询stu集合中age>18的数据
- db.stu.find({age:{$gt:18}})
- 5.如果是 age 大于 50 小于 80
- 不能这样写:db.posts.find( { age: { $gt: 50 }, qty: { $lt: 80 } } )
- 应该这样写:db.posts.find( { age: { g t : 50 , gt: 50 , gt:50,lt: 80}} )
格式:{ field: {符号: value}}
$eq 等号 equal
$gt 大于 great
$gte 大于等于 great equal
$lt 小于 less than
$lte 小于等于 less than equal
$ne 不等于 not equal
$in 在范围内
$nin 不在范围内
-
5.查找stu集合中name域中以“华为”字符的开头的数据
- db.stu.find({name:/^华为/})
-
6.查询stu集合中name='手机1’和name='手机2’的数据
- db.stu.find({name:{$in:[‘手机1’,‘手机2’]}})
格式:{ field:{符号:[value1,value2,....]}}
$in 在范围内
$nin 不在范围内
-
7.查找name="华为手机"并且price:800的数据
- db.stu.find({name:“华为手机”,price:800})
-
8.查询stu集合中name=‘华为手机’ 或者 price<1000的数据
- db.stu.find({$or:[ {name:‘华为手机’},{price:{$lt:1000}} ]})
-
9.查询stu集合中price<=100的数据,不存在price属性的数据也会查询出来
- db.stu.find({price:{$not:{$gt:100}}})
-
10.AND 和 OR联合使用
- db.col.find({“likes”: {$gt:50}, $or: [{“by”: “菜鸟教程”},{“title”: “MongoDB 教程”}]}).pretty()
格式:$or:[{},{},....]
$or 或者
$and 并且
$nor 与$or相反
$not 取反
- 11.查询stu集合中包含域名称为price的数据
- db.stu.find({price:{$exists: true}})
- 12.查询stu集合中name属性为字符串类型的数据
- db.stu.find({name:{$type:2}})
格式:
$exists: true
$type:2 (type操作符不细讲)
- 13.查询products集合中name='华为手机’的数据
db.products.find({
$where: function(){
return this.name == '华为手机'
}
})
- 14.查询products集合中name域中包含“华为手机”字符的数据
db.products.find({
$where: function(){
return this.name.indexOf('华为手机') > -1;
}
})
格式:
$where: function(){
return xxx;
}
- 15. 修 改 内 嵌 文 档 的 属 性 \color{red}修改内嵌文档的属性 修改内嵌文档的属性(外文档的内文档的属性)
极 重 要 的 实 例 \color{red}极重要的实例 极重要的实例
{
_id:xxxxxxxx,
name:"zhangsan",
hobby:{
citys:[
"hangzhou","BeiJing","shanghai"
],
movie:[
"movie-a","movie-b"
]
}
}
向name:zhangsan的文档中添加一个age:20
db.stu.update({name:zhangsan},{$set:{age:20}})
//通过内嵌文档来对文档查询,必须其属性名要加引号“”和'.'号连接
查询喜欢电影movie-a的文档
db.stu.find({"hobby.movie":"movie-a"})
//push在数组中添加,如果数组中已存在,还继续添加
向name:zhangsan中添加一个新的元素movie-c
db.ustu.updata({name:"zhangsan"},{$push:{"hobby.movie":"movie-c"}})
//addToSet在数组中添加,如果数组中已存在,不添加
向name:zhangsan中添加一个新的元素movie-c
db.ustu.updata({name:"zhangsan"},{$addToSet:{"hobby.movie":"movie-c"}})
集合查询函数
-
14.查询users集合中不重复的name属性,返回的是数组
- db.stu.distinct(‘name’)
-
15.查询stu集合中name='zhangshan’的数据数量
- db.stu.count({name:‘zhangshan’})
3.更新
- 1.update()
更
新
已
存
在
的
文
档
\color{red}更新已存在的文档
更新已存在的文档
- $set 数据存在则更新,更改属性列表,不在列表中其他属性会被保留,如果不加此符号,其它属性会被丢弃(_id属性不会丢失)
- $unset 数据存在时不进行操作,移除集合中的键值对
- $setOnInsert 数据存在时不进行操作
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
}
)
query 查询条件,类似sql内where后面的
update 类似sql内set后面的
upsert 可选,如果不存在,是否插入,
true为插入,默认是false,不插入。
multi 可选,默认是false,只更新找到的第一条记录,
true,就把按条件查出来多条记录全部更新。
writeConcern 可选,抛出异常的级别。
例子:
只会修改第一条发现的文档
>db.stu.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}})
修改多条相同的文档
>db.stu.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}},{multi:true})
$set用来在原有属性上,添加指定属性
$unset用来删除指定属性,其他属性不变
不存在-只添加第一条:
db.col.update( { "count" : { $gt : 4 } } , { $set : { "test5" : "OK"} },true,false );
不存在-全部添加进去:
db.col.update( { "count" : { $gt : 5 } } , { $set : { "test5" : "OK"} },true,true );
已存在-只更新第一条记录:
db.col.update( { "count" : { $gt : 10 } } , { $inc : { "count" : 1} },false,false );
已存在-全部更新:
db.col.update( { "count" : { $gt : 3 } } , { $set : { "test2" : "OK"} },false,true );
- 2.save() 传 入 的 文 档 来 替 换 已 有 文 档 \color{red}传入的文档来替换已有文档 传入的文档来替换已有文档
db.collection.save(
<document>,
{
writeConcern: <document>
}
)
document 文档数据。
writeConcern 可选,抛出异常的级别。
例子:
替换了 _id 为 56064f89ade2f21f36b03136 的已存在的文档数据
>db.col.save({
"_id" : ObjectId("56064f89ade2f21f36b03136"),
"title" : "MongoDB"
})
- 3.updateOne() 向 指 定 集 合 更 新 单 个 文 档 \color{red}向指定集合更新单个文档 向指定集合更新单个文档
- 4.updateMany() 向 指 定 集 合 更 新 多 个 文 档 \color{red}向指定集合更新多个文档 向指定集合更新多个文档
例子:
更新单个文档
> db.stu.updateOne({"name":"abc"},{$set:{"age":"28"}})
更新多个文档
> db.stu.updateMany({"age":{$gt:"10"}},{$set:{"status":"xyz"}})
- 5.replaceOne() 替 换 单 个 文 档 \color{red}替换单个文档 替换单个文档
4.删除
-
1.remove()即使把集合stu中的所有数据都删除了stu集合仍然存在
- 需要继续执行 db.repairDatabase() 来回收磁盘空间。
-
2.drop()不仅会删除数据,还会把集合的结构给删除
-
3.deleteOne()
-
4.deleteMany()
db.collection.remove(
<query>,
<justOne>
)
query 可选,删除文档的条件。
justOne 可选,如果设为 true 或 1,则只删除一个文档,
如果不设置,或默认值 false,则删除所有匹配条件的文档。
writeConcern 可选,抛出异常的级别。
例子:
1.
删除stu集合中name='abc'的文档(所有)
db.stu.remove({name:'abc'})
删除stu集合中name='abc'的文档(一个)
db.stu.remove({name:'abc'},true)
2.删除 status 等于 A 的一个文档
db.stu.deleteOne( { status: "A" } )
3.删除 status 等于 A 的全部文档
db.stu.deleteMany({ status : "A" })
4.清空集合stu文档,保留数据【性能差】
db.stu.remove({})
5.清空集合stu文档,不保留数据【性能好】
db.stu.drop()
6.删除集合下全部文档
db.stu.deleteMany({})
极 重 要 的 实 例 : ( 现 实 中 不 能 真 的 删 除 数 据 ) \color{red}极重要的实例:(现实中不能真的删除数据) 极重要的实例:(现实中不能真的删除数据)
设置isDel为已经删除的意思:0=未删除,1=删除
db.stu.insert({
{
name:"zhangsan",
idDel:0
},
{
name:"lisi",
idDel:0
},
{
name:"wangwu",
idDel:0
},
})
//更新name:zhangsan,将isDel:0改为1,即表示删除了,但实际并没有删
db.stu.updataOne({name:zhangsan},{$set:{isDel:1}});
//给用户看的显示数据只需调用isDel:0的数据即可
db.stu.finf({isDel:0});
5.排序
- sort(keys)
- Keys 为要创建的索引字段:1 为升序排列,-1 是降序排列
按字段 key 的升序排列
>db.COLLECTION_NAME.find().sort({KEY:1})
按字段 likes 的降序排列,且显示title,不显示_id字段
>db.col.find({},{"title":1,_id:0}).sort({"likes":-1})
注:
skip(), limilt(), sort()三个放在一起执行的时候,执行的顺序是
先 sort(), 然后 skip(),最后 limit()。
6.1索引
- createIndex(keys, options)
- Keys 为要创建的索引字段:1 为升序排列,-1 是降序排列
- options 有很多
1.对title字段按升序索引
>db.stu.createIndex({"title":1})
2.多个字段创建索引
>db.stu.createIndex({"title":1,"description":-1})
3.后台创建索引
db.stu.createIndex({open: 1, close: 1}, {background: true})
4.查看集合索引
db.stu.getIndexes()
5.查看集合索引大小
db.stu.totalIndexSize()
6.删除集合所有索引
db.stu.dropIndexes()
7.删除集合指定索引
db.stu.dropIndex("索引名称")
另:
数据记录中有日期类型,可以设置定时自动删除任务(单字段索引,混合索引不支持)
{expireAfterSeconds: 180}设置为180秒后删除索引
db.col.createIndex({"createDate": 1},{expireAfterSeconds: 180})
6.2覆盖索引查询、查询分析、查询限制、全文检索
1.索引存在于RAM中,从索引中获取数据比通过扫描文档读取数据要快得多
很少对集合进行读取操作,建议不使用索引
2.
所
有
索
引
字
段
是
一
个
子
文
档
\color{red}所有索引字段是一个子文档
所有索引字段是一个子文档
3.db.xxx.ensureIndex()
4.db.xxx.ensureIndex().explain()
5.db.xxx.ensureIndex().hint()
6.$search
现有例子
{
"_id": ObjectId("53402597d852426020000002"),
"gender": "male",
"name": "zhangsan",
"tags": [
"music",
"cricket",
"blogs"
],
"address": {
"city": "Los Angeles",
"state": "California",
"pincode": "123"
},
"commit":"This ia a commint"
}
1.创建索引(0不显示,1显示)
>db.users.ensureIndex({gender:1,name:1})
2.通过索引查找
>db.users.find({gender:"male"},{name:1,_id:0})
3.查询分析
>db.users.find({gender:"male"},{name:1,_id:0}).explain()
>db.users.find({gender:"male"},{name:1,_id:0}).hint()
1.索引数组字段,加引号(tags是数组)
>db.users.ensureIndex({"tags":1})
2.通过索引查找包含的字段的文档
>db.users.find({tags:"cricket"})
1.索引子文档字段,加引号(address是子文档对象)
>db.users.ensureIndex({"address.city":1,"address.state":1,"address.pincode":1})
2.通过索引查找
>db.users.find({"address.city":"Los Angeles"})
>db.users.find({"address.city":"Los Angeles","address.state":"California","address.pincode":"123"})
1.全文检索,加引号(a是commit的自定义别名,加引号)
>db.users.ensureIndex({"commit":"a"})
2.查找包含特定的内容
>db.users.find({$a:{$search:"This"}})
3.删除全文索引(先查找全文索引名,再删除)
>db.users.getIndexes()
>db.posts.dropIndex("a")
查询限制
1.正则表达式及非操作符,如 $nin, $not, 等。
2.算术运算符,如 $mod等。
3.$where 子句
7.聚合
用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果
- db.stu.aggregate(AGGREGATE_OPERATION)
聚合框架常用操作:
$match 过滤数据,只输出符合条件的文档。
$limit 限制返回的文档数。
$skip 跳过指定数量的文档,并返回余下的文档。
$project 是否显示文档结构。重命名、增加、删除域、创建计算结果、嵌套文档
$unwind 文档中某一个数组类型字段拆分成多条,每条包含数组中的一个值。
$group 文档分组,用于统计结果。
$sort 文档排序后输出。
$geoNear 输出接近某一地理位置的有序文档。
$group实例
聚合表达式
$sum 计算总和。
$avg 计算平均值。
$min 获取集合中所有文档对应值得最小值。
$max 获取集合中所有文档对应值得最大值。
$push 在结果文档中插入值到一个数组中,若重复会再创建。
$pushAll 同$push,只是一次可以追加多个值到一个数组字段内。
$pop 在结果文档中删除数组的第一个或最后一个元素。
$addToSet 在结果文档中插入值到一个数组中,若重复不会再创建。
$first 根据资源文档的排序获取第一个文档数据。
$last 根据资源文档的排序获取最后一个文档数据。
$rename 修改字段名称
$bit 位操作,integer类型
例:
db.stu.aggregate([{$group:{_id:"$by_user",url:{$push:"$url"}}}])
db.stu.aggregate([{$group:{_id:"$by_user",first_url:{$first:"$url"}}}
db.stu.aggregate([{$group:{_id:"$by_user",last_url:{$last:"$url"}}}])
{ $push : { field : value } }
{ $pushAll : { field : value_array } }
{ $pull : { field : _value } }
{ $pop : { field : 1 } }
{ $rename : { old_field_name : new_field_name } }
{ $bit : { field : {and : 5}}}
$project实例
0显示,1不显示,默认情况下_id字段是被包含的,想不包含的话_id : 0
db.stu.aggregate(
{
$project : {
title : 1 ,
author : 1 ,
}
}
);
$match实例
db.articles.aggregate( [
{ $match : { score : { $gt : 70, $lte : 90 } } },
{ $group: { _id: null, count: { $sum: 1 } } }
] );
8.一对一、一对多、多对多的联系
8.1 ObjectId
- ObjectId 是一个12字节 BSON 类型数据
- 前4个字节:时间戳
- 紧接的3个字节:机器标识码
- 紧接的两个字节:进程id组成(PID)
- 最后三个字节:随机数。
1.创建新的ObjectId
>newObjectId = ObjectId()
2.获取文档的创建时间
>ObjectId("xxxxxxxxxxxxxxxxxxxxx").getTimestamp()
3.ObjectId 转换为字符串
>new ObjectId().str
8.2 指定的序列会自动增长 1 并返回最新序列值
(最好不要对_id调用这个函数)
1.自己创建自增函数
>function Autoincrement(sequenceName){
var sequenceDocument = db.counters.findAndModify(
{
query:{_id: sequenceName },
update: {$inc:{sequence_value:1}},
"new":true
});
return sequenceDocument.sequence_value;
}
2.调用自增函数
>db.user.insert({
"userid":Autoincrement("userid"),
"name":"zhangsan"})
>db.user.insert({
"userid":Autoincrement("userid"),
"name":"lisi"})
3.读取文档
>db.user.find()
输出:
{ "_id" : ObjectId(xxxxxxx), "userid" : 1, "name" : "zhangsan"}
{ "_id" : ObjectId(xxxxxxx), "userid" : 2, "name" : "lisi"}
1.一对一:如夫妻
wifeAndHusband集合
db.wifeAndHusband.insert([
{
name:"男1"
wife:{
name:"女1"
}
},
{
name:"男2"
wife:{
name:"女2"
}
},
]);
2. 一 对 多 ( 相 当 于 m y s q l 的 外 键 、 多 表 查 询 ) : 如 文 章 和 评 论 \color{red}一对多(相当于mysql的外键、多表查询):如文章和评论 一对多(相当于mysql的外键、多表查询):如文章和评论
article集合(文章)
db.article.insert([
{
article:"a"
},
{
article:"b"
}
]);
假设find()后,id为12个标准字节
{"_id":ObjectId("xxxxxxxxxxx1"),"article":"a"}
{"_id":ObjectId("xxxxxxxxxxx2"),"article":"b"}
comment集合(评论)
db.comment.insert([
list:["评论1","评论2","评论3"]
article_id:ObjectId("xxxxxxxxxxx1")
]);
db.comment.insert([
list:["评论4","评论5"]
article_id:ObjectId("xxxxxxxxxxx1")
]);
db.comment.insert([
list:["评论1","评论2","评论3"]
article_id:ObjectId("xxxxxxxxxxx2")
]);
此时两表已关联
先查找文章a(一篇)的评论的所有_id:
var article = db.article.findOne({article:"a"})._id;
再查找所有与文章a的_id有关的评论:
db.comment.find({article_id:article});
3.
多
对
多
(
相
当
于
m
y
s
q
l
的
外
键
、
多
表
查
询
)
:
如
老
师
和
学
生
\color{red}多对多(相当于mysql的外键、多表查询):如老师和学生
多对多(相当于mysql的外键、多表查询):如老师和学生
把_id变成一个数组
teachers集合
db.teachers.insert([
{teachername:"老师1"},
{teachername:"老师2"},
{teachername:"老师3"},
]);
假设find()后,id为12个标准字节
{"_id":ObjectId("xxxxxxxxxxx1"),"teachername":"老师1"}}
{"_id":ObjectId("xxxxxxxxxxx2"),"teachername":"老师2"}}
{"_id":ObjectId("xxxxxxxxxxx3"),"teachername":"老师2"}}
students集合
db.students.insert([
{
stuname:"学生1",
teacher_id:[
ObjectId("xxxxxxxxxxx1"),
ObjectId("xxxxxxxxxxx2")
]
},
{
stuname:"学生2",
teacher_id:[
ObjectId("xxxxxxxxxxx1"),
ObjectId("xxxxxxxxxxx3")
]
},
{
stuname:"学生3",
teacher_id:[
ObjectId("xxxxxxxxxxx2"),
ObjectId("xxxxxxxxxxx3")
]
},
]);
此时两表已关联
先查找老师1(一个)的所有_id:
var teacher = db.teachers.findOne({teachername:"老师1"})._id;
再查找所有与老师1的_id有关的学生:
db.students.find({teacher_id:teacher});
9.多表查询深入
第13课