MongoDB安装与简单了解
首先呢 是安装MongoDB数据库。window上安装可以点击这里去下载安装。下载msi文件安装后,会在电脑上安装mongoDB这个非关系型数据库,和一个可视化的图形工具 MongoDB Campass (4.0版本)。刚才也提到了,MongoDB是个非关系型数据库,那么他和我们常用的关系型数据库有啥差异呢?
简单来说有如下对应关系
详细的看如下图所示
看上图中 一个数据行是以json 形式记录的,可以知道MongoDB 使用JSON(JavaScript ObjectNotation)文档存储记录。但是呢文档document的存放形式是类似于json 的Bjson格式存放的,也就是MongoDB中document以BSON形式存放。BSON目前主要用于MongoDB中,是MongoDB的数据存储格式。BSON基于JSON格式,选择JSON进行改造的原因主要是JSON的通用性及JSON的schemaless的特性。
了解了基本数据格式我们开始操作数据库吧。首先我们先通过MongoDB Campass 这个工具简单操作一下数据库,了解一下collection集合 和document 是啥样的。
Mongodb campass 工具的初识
1.创建 database
2.创建collection
找到要创建位置所在的数据库。点击右侧的CREATE COLLECTION,输入集合名字就能创建collection。
3.插入 document
点击进入 collection 在collection 上面有个 insert document 按钮,点击输入字段,字段类型 然后点击insert
4. 插入 field
在插入document的时候 可以添加字段:属性, 属性名, 属性类型
创建完成后list形式如下图所示
好了,通过自带的工具,我们了解到了前面说的collection集合和document是什么样式的,我们可以在命令行中进行数据库的相关操作了。
Mongo基本命令行
1.查看已有的数据库及其数据集合
(1)cmd输入 mongo 进入mongo环境, 显示出你的mongodb基本信息,
show dbs
查看本地的所有数据库列表。在列表中我们可以看到我们之前通过工具创建的数据库。
(3)use
创建/切换数据库。use parkappdb
是数据库名称。如果use后面的数据库存在,则切换到该数据库,如果不存在则创建。当我们切换到指定数据库后,不放心我们使用的数据库是否是我们要操作的数据库咋办?不用担心。我们可以输入 db
指令 查看当前所用数据库名称
(4)show collections
显示当前数据库中的集合(类似关系数据库中的表)
2.查、增、改、删 操作
(1)查询
查询集合中存在的document数据记录。可使用 指令 db.collectionName.find()
db.users.find():对于当前数据库中的users集合进行数据查找(由于没有条件,会列出所有数据)。find方法里面可以传递参数(查询条件)。为了方便我们查看,我们可以使用db.users.find().pretty() 将查询结果格式化输出。
(2)新增集合,插入数据
创建集合:db.createCollection(name, options)
,name是集合名称,options是可选参数, 指定有关内存大小及索引的选项。集合不存在也会自动创建。创建后我们可以在工具中查看集合的创建情况。
插入数据: db.testdb.insert({"test": "测试用例"})
在操作前可以对比工具中显示的数据情况,对比操作后的差异,会看到本没这个数据集合,但是这个插入语句执行后 自动添加了一个collection 并填充数据
(3)更新修改数据
a)update 命令更新
基本语法如下
db.colletionName.update(
,
{
upsert:,
multi: ,
writeConcern:
}
)复制代码
- query : update的查询条件,类似sql update查询内where后面的。
- update : update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的
- upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
- multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
- writeConcern :可选,抛出异常的级别。
其他的修改操作符有
$inc
修改器只是使用与数字类型,他可以为指定的键对应的数字类型的数值进行加减操作.
$unset
修改器用法很简单,就是删除指定的键值对。
$push
修改器:
1.如果指定的键是数组增追加新的数值
2.如果指定的键不是数组则中断当前操作。
会有提示 Cannot apply $push/$pushAll modifier to non-array
3.如果不存在指定的键则创建数组类型的键值对
4.此方法可添加重复数据
$pushAll
修改器用法和$push
相似,它可以批量添加数组数据 ,可以添加整个数组
$addToSet
修改器是如果目标数组存在此项则不操作,不存在此项则加进去,即不添加重复 数据。
$pop
修改器从指定数组删除一个值1删除最后一个数值,-1删除第一个数值。
$pull
修改器是删除一个被指定的数值。
$pullAll
修改器是一次性删除多个指定的数值。
$rename
对字段进行重命名
以上操作符 请自己实际操作一下,不在赘述了。
MongoDB的CURD参考1
b)save命令 db.collection.save(obj)
obj代表需要更新的对象,如果集合内部已经存在一个和obj相同的"_id"的记录, Mongodb会把obj对象替换集合内已存在的记录,如果不存在,则会插入obj对象。
(4)删除
db.[collectionName].remove({key:value})
根据条件删除数据
db.[collectionName].remove({})
删除集合中所有数据 而集合的本身和索引不会被删除
db.[collectionName].remove({})
删除集合中所有数据 ,集合的本身和索引不会被删除
db.collection.drop()
删除整个集合。集合、索引都不存在了
经过以上操作。我们基本熟悉了 mongodb 命令行的相关操作。接下来我们看看如何给mongodb 设置权限,设置用户名密码
3.MongoDB 设置权限 (设置用户名密码)
在设置某个数据库用户名密码之前要先设置数据库用户管理员
(1)创建用户管理员,设置最高权限
a) use admin 切换数据库,进入admin 数据库下进行创建
use admin
db.createUser({
user:'root',
pwd:'root',
roles:[{role:"root",db:"admin"}]
})复制代码
创建成功会有相应提示
MongoDB数据库角色有如下所示
-
- 数据库用户角色:read、readWrite;
- 数据库管理角色:dbAdmin、dbOwner、userAdmin;
- 集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;
- 备份恢复角色:backup、restore;
- 所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
- 超级用户角色:root // 这里还有几个角色间接或直接提供了系统超级用户的访问 (dbOwner 、userAdmin、userAdminAnyDatabase)
- 内部角色:__system
角色说明:
-
- Read:允许用户读取指定数据库
- readWrite:允许用户读写指定数据库
- dbAdmin:允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问 system.profile
- userAdmin:允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户
- clusterAdmin:只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。
- readAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读权限
- readWriteAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读写权限
- userAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的userAdmin权限
- dbAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。
- root:只在admin数据库中可用。超级账号,超级权限
b)修改配置文件,开启安全认证
authorization: enabled #注意缩进,enabled 前面有个空格。
c)进行认证
'db.auth(用户名,用户密码)'
认证只能在admin 库下进进行认证,在其他库下认证会不通过,在admin 认证后可以去其他库进行操作如果返回 '1'表示验证成功,如果是 '0' 表 示验证失败
(2)为某个数据库设置用户权限
首先确定以用户管理员的身份登录 admin 数据库。然后用 use 命令切换到目标数据 库,同样用 db.createUser() 命令来创建用户,其中角色名为 “readWrite” >
>use test
switched to db test
> db.createUser({
user:"testuser",
pwd:"testpass",
roles:["readWrite"]})
Successfully added user: { "user" : "testuser", "roles" : [ "readWrite" ] }
> db.auth("testuser","testpass")
1复制代码
Mongoose使用
Mongoose是MongoDB的一个对象模型工具,是基于node-mongodb-native开发的MongoDB nodejs驱动,可以在异步的环境下执行。同时它也是针对MongoDB操作的一个对象模型库,封装了MongoDB对文档的的一些增删改查等常用方法,让NodeJS操作Mongodb数据库变得更加灵活简单
Mongoose的api
在使用这个框架工具之前呢先简单了解一下几个概念,因为在Mongoose中会用到。
Schema:
一种以文件形式存储的数据库模型骨架,无法直接通往数据库端,也就是说它不具备对数据库的操作能力.可以说是数据属性模型(传统 意义的表结构),又或着是“集合”的模型骨架。Schema是以key-value形式Json格式的数据
model:
数据模型,模型具有对数据库操作的能力。我们需要将 schema转换为model 进行数据操作
1.安装mongoose到项目里
npm install mongoose
2. 引入mongoose
consnt mongoose = require('mongoose')
3.连接数据库
先确定数据库地址。格式为 mongodb://userName:pwd@ip:port/dbname
例如 mongodb://root:root@localhost:27017/test
connect 方式连接
//--------创建连接 ------------
mongoose.connect(DBURL,function(err){
if(err){
console.warn('数据库连接失败:'+err);
}else {
console.log('数据库成功连接到');
}
});
//---------创建一个Schema ----------
var userchema = mongoose.Schema({
testIndex:Number,
testName:String,
testVal:'string'
})
//---------创建model---------------
var userModel = mongoose.model('user',userchema,‘集合名字’ );
//--参数一为Model的名字,参数二为生成Model所需要的schema,Model就像是schema所编译而成的一样。 //--默认情况下model会自动根据 user 这个名字 加上s 即 users 为集合collection 的名字。
//我们可以自定义集合的名字,有如下2种写法
//-----------方式1-------------------------------------
//var userchema = mongoose.Schema({},{ collection:'集合名字' } )
//userModel = mongoose.model('user',userchema );
//-----------方式2-------------------------------------
// var userchema = mongoose.Schema({})
//var userModel = mongoose.model('user',userchema,‘集合名字’ );
复制代码
schemas中的数据类型有以下几种:
String :字符串类型
Number :数字类型
Date : 日期类型
Boolean :boolean类型
Buffer :NodeJS buffer类型
ObjectId :主键,一种特殊而且非常重要的类型
Mixed : 混合类型 , Schema = new mongoose.Schema({any:{mixed}})
Array: 集合类型
connect + connection 方式连接
因为connect()方法并不能监听数据库连接情况,而connection是mongoose模块的默认引用,返回一个Connetion对象。所 以 connect 和connection 搭配使用,可以对数据库连接情况监听。
mongoose .connect(DBURL)
var mgdbconect =mongoose.connection;
mgdbconect.on('状态',function(){})
//----可选状态有 connected disconnected error
//---创建schmea 和创建 model 跟上述一致复制代码
createConnection() 方式连接
mongoose.createConnection([uri], [options], [options.config],
[options.config.autoIndex, [options.useMongoClient])
//--此方法获取数据库连接,操作database层面,返回一个Connection对象。
//Connection对象中包含model,collection,dropDatabase等操作数据库的方法,
//也包含connected,disconnected,error等事件触发方法。
//---具体操作请查阅相关资料复制代码
上述几种方式简单区别如下
1、createConnetion()方法的返回值是一个Connetion,可以使用createConnetion操作多个数据库。
2、connet()方法的返回值中包含了一个mongoose的引用,所以在项目中只能对一个数据库操作,而在操作多个数据库的情况下,可以 使用createConnetion()方法。
3、connection是mongoose模块的默认连接。返回一个Connetion对象
4.查询数据
Mongoose 模型提供了 find, findOne, 和 findById 方法用于文档查询
Model.find(query, fields, options, callback) // fields 和 options 都是可选参数
//query 查询条件, fields 要查询字段 ,options 配置项 ,callback 回调函数
在第二个参数中,指定键名且值为1或者true则是查询结果中显示的键;若值为0或者false,则为不显示键。文档中的键若在参数中没有指定,查询结果中将不会显示(_id例外)。_id是默认显示的,除非进行手动设置为0或者false则不显示。
//--- UserModel 是上面进行数据库连接的时候创建的model
UserModel.find({},function(err,docs){
if(err){
console.log('查询出错啦')
}else{
console.log('全部查询结果--',docs)
}
});
//----查询 testname 为测试 的数据,并返回 testIndex testVal 这两个字段的结果
UserModel.find({testName:'测试'},{testIndex:1,testVal:1},{},function(err,docs){
if(err){
console.log('查询出错啦')
}else{
console.log('testName==测试-查询结果--',docs)
}
});复制代码
Model.findOne
与 Model.find 相同,但只返回单个文档
Model.findOne({ userNname:"张三"},function(err, doc){// doc 是单个文档});
Model.findById
与 findOne 相同,但它接收文档的 _id 作为参数,返回单个文档。_id 可以是字符串或 ObjectId 对象。
Model.findById(obj._id,function(err, doc){// doc 是单个文档});
按照条件查询
Model.countDocuments
返回符合条件的文档数。
Model.countDocuments(conditions, callback);
Model.distinct
查询符合条件的文档并返回根据键分组的结果。
Model.distinct(field, conditions, callback);
Model.where (path, [val])
path实际上就是字段, 第二个参数val表示可以用来指定path = val的数据内容
//--多条件查询示例 查询testIndex大于3,且testname为测试的数据
Model.where('testIndex').gt(3).
where({'testName':'测试'}).
select('testVal').
exec(function(err,res){
console.log('testIndex大于3,且testname为测试 的结果--',err,res)
});复制代码
Model.$where
有时我们需要在 mongodb 中使用 javascript 表达式进行查询,这时可以用 find({$where : javascript}) 方式,$where 是一种快捷方式,并支持链式调用查询。
//--示例
UserModel.$where('this.testName === this.testVal').exec(function(err,res){
console.log('name val相同的结果---',err,res)
});复制代码
以上查询都带有返回函数。如果不提供回调函数,所有这些方法都返回 Query 对象,它们都可以被再次修改(比如增加选项、键等),直到调用 exec 方法。
var query =Model.find({});
query.where('field',5);
query.limit(5);
query.skip(100);
query.exec(function(err, docs){
// called when the `query.complete` or `query.error` are called// internally
});
//--以上callback 函数 返回的第一个参数是err 第二个参数是doc 查询结果存放于doc中 复制代码
更多参考 www.cnblogs.com/chris-oil/p…
5.新增数据
新增数据有2种方式 model.create() 和 model.save()
mode.create()可以一次性新增多条数据
mode.save() 需要实例化 model 才能新增 所以只能新增一条数据
//------create新增
UserModel.create(
{testIndex:12,testName:'create的数据',testVal:'create的数据'},
{testIndex:13,testName:'create的数据',testVal:'create'},
function(err,doc){
console.log('create创建2条数据结果---',err,doc)
});
//---save 新增--
const testUserModel = new UserModel({
testIndex:14,
testName:'save的数据',
testVal:'save'
})
testUserModel.save(function(err,doc){
console.log('save创建1条数据结果---',err,doc)
});
复制代码
6. 更新数据
doc:需要修改的数据,不能修改主键(_id);
options:控制选项;
callback:回调函数,返回的是受影响的行数。
options有以下选项:
safe (boolean): 默认为true。安全模式。
upsert (boolean): 默认为false。如果不存在则创建新记录。
multi (boolean): 默认为false。是否更新多个查询记录。
runValidators: 如果值为true,执行Validation验证。
setDefaultsOnInsert: 如果upsert选项为true,在新建时插入文档定义的默认值。
strict (boolean): 以strict模式进行更新。
overwrite(boolean) 默认为false。禁用update-only模式,允许覆盖记录
// -----更新 修改 Model.update(conditions, doc, [options], [callback])
UserModel.update({ testName:'save的数据'},{testName:'手机',testVal:'oppo'},function(err,doc){
console.log('更新一条数据--',err,doc)
});
UserModel.update({testName:'create的数据'},{testName:'快递',testVal:'顺丰'},{multi: true},
function(err,doc){
console.log('更新多条数据--',err,doc)
});复制代码
其他的更新方法
Model.updateMany(conditions, doc, [options], [callback]) //一次更新多条 Model.updateOne(conditions, doc, [options], [callback]) //一次更新一条 Model.findByIdAndUpdate(id, [update], [options], [callback])
Model.findOneAndUpdate([conditions], [update], [options], [callback])
根据id进行更新;此id就是数据库中自动生成的id ,
id:指定_id的值;
update:需要修改的数据;
options控制选项;
callback回调函数。
options有以下选项:
new:bool - 默认为false。返回修改后的数据。
upsert: bool - 默认为false。如果不存在则创建记录。
runValidators: 如果值为true,执行Validation验证。
setDefaultsOnInsert: 如果upsert选项为true,在新建时插入文档定义的默认值。 sort: 如果有多个查询条件,按顺序进行查询更新。
select: 设置数据的返回。
passRawResult: 如果为真,将原始结果作为回调函数第三个参数。
7.删除
Model.remove(conditions, [callback]) //---删除
UserModel.remove({testName:'待删除'},function(err,docs){
console.log('删除了-',err,docs)
}) //--删除“testName”值为“待删除”的记录。复制代码
Model.findByIdAndRemove(id, [options], [callback])
Model.findOneAndRemove(conditions, [options], [callback])
id:指定_id的值;
conditions:查询条件;
update:需要修改的数据;
options控制选项;
callback回调函数。
options有以下选项:
sort: 如果有多个查询条件,按顺序进行查询更新。
select: 设置数据的返回。
maxTimeMS: 查询用时上限。
附上本文示例代码
var mongoose = require('mongoose'),
DB_URL ='mongodb://appadmin:admin@localhost:27017/parkappdb';
/* 连接*/
mongoose.connect(DB_URL,{ useNewUrlParser: true });
var mgdbconect =mongoose.connection;
mgdbconect.on('connected',function(){
console.log('已连接');
})
mgdbconect.on('error',function(error){
console.log('连接出错:' +error);
})
mgdbconect.on('disconnected',function(){
console.log('未连接');
})
//--定义数据结构模板
const userSchema = new mongoose.Schema({
testIndex:Number,
testName:String,
testVal:'string'
})
//---modle 实例化 schema
const UserModel = mongoose.model('user',userSchema,'testDEMO')
// Mongoose 模型提供了 find, findOne, 和 findById 方法用于文档查询。
// Model.find(query, fields, options, callback)// fields 和 options 都是可选参数
UserModel.countDocuments({},function(err,res){
console.log('计数--',err,res)
console.log("----------------------------")
})
//查询 ----------------------------------------------------
UserModel.find({},function(err,docs){
if(err){
console.log('查询出错啦')
}else{
console.log('全部查询结果--',docs)
console.log("----------------------------")
}
});
UserModel.find({testName:'测试'},{testIndex:1,testVal:1},{},function(err,docs){
if(err){
console.log('查询出错啦')
}else{
console.log('testName==测试-查询结果--',docs)
console.log("----------------------------")
}
});
UserModel.where('testIndex').gt(3).where({'testName':'测试'}).select('testVal').exec(function(err,res){
console.log('testIndex大于3,且testname为测试 的结果--',err,res)
console.log("----------------------------")
});
UserModel.$where('this.testName === this.testVal').exec(function(err,res){
console.log('name val相同的结果---',err,res)
console.log("----------------------------")
});
//------新增
UserModel.create(
{testIndex:12,testName:'create的数据',testVal:'create的数据'},
{testIndex:13,testName:'create的数据',testVal:'create'},
function(err,doc){
console.log('create创建2条数据结果---',err,doc)
});
const testUserModel = new UserModel({
testIndex:14,
testName:'save的数据',
testVal:'save'
})
testUserModel.save(function(err,doc){
console.log('save创建1条数据结果---',err,doc)
});
// -----更新 修改 Model.update(conditions, doc, [options], [callback])
UserModel.update({ testName:'save的数据'},{testName:'手机',testVal:'oppo'},function(err,doc){
console.log('更新一条数据--',err,doc)
});
UserModel.update(
{ testName:'create的数据'},{testName:'快递',testVal:'顺丰'},{multi: true},function(err,doc){
console.log('更新多条数据--',err,doc)
});
//---删除
UserModel.remove({testName:'待删除'},function(err,docs){
console.log('删除了-',err,docs)
})
复制代码
以上就是关于MongoDB 及其mongoose工具的入门讲解及示例。因为是刚学习,有许多理解不准确的地方,还望大家指出,多多学习。thxs