MongoDB
1、什么是MongoDB
- MongoDB是一个基于分布式文件存储 的数据库。是为了快速开发互联网web应用而设计的数据库系统。
- MongoDB的设计目标是极简、灵活、作为Web应用栈的一部分。
- MongoDB的数据模型是面向文档的,所谓文档是一种类似于JSON的结构,简单理解MongoDB这个数据库中存的是各种各样的JSON
2、三个概念
- 数据库
–数据库是一个仓库,在仓库中可以存放集合 - 集合
–集合类似于数组,在集合中可以存放文档。 - 文档
–文档数据库中的最小单位,我们存储和操作的内容都是文档。
3、基本指令
- 在MongoDB中,数据库和集合都不需要自己手动创建,当我们创建文档时,如果所在的集合或数据库不存在会自动的创建数据库和集合。
- show dbs :显示当前的所有数据库
- use 数据库 :进入到指定的数据库中
- db :db表示的是当前所处的数据库
- show collections :显示数据库中所有的集合。
- MongoDB的CRUD操作详情请看官方文档
3.1、插入操作
- db.集合.insert({key:value}),向集合中插入一个或者多个文档
- 当我们向集合中插入文档时,如果没有给文档指定_id属性,则数据库会自动为文档添加_id属性来作为文档的唯一标识(该id是以时间戳和机器码来生成的),
- 我们可以调用ObjectId()来生成
3.2、查找集合
db.集合.find()
- find()用来查询集合中多有条件符合的文档、
- find()可以接受一个集合中所有的文档
- {}表示查询集合中所有的文档
- {属性:值}查询属性是指定值得文档
- db.collections.find({字段}),返回的是一个数据
- db.collections.findOne()返回的是一个对象。如果在后面 点上属性就会查出该属性
- db.stus.count() / length()查询集合中有多少条数据
3.3、修改操作
- db.collection.update{查询对象,新对象}
- update()默认情况下会使用新的对象来替换旧对象
- 如果需要修改指定的属性,而不是替换掉需要使用“修改操作符”来完成修改 $set 可以用来修改文件中的指定属性。
这样会把没有匹配的置空
应该使用修改操作符。
- $unset表示删除一个字段,用法与 $set相似
- db.collections.updateMany():同时修改多个符合条件的文档。
- db.collection.updateOne():修改一个符合条件的文档。
- db.collection.updateOne()
3.4、删除文档
- db.collection.remove() :根据条件删除文档,传递条件的方式和find一样一样。第二个参数传递一个true,就会只删除一个。和deleteOne一样。
- db.collection.deteleOne()
- db.collection.deleteMany()
- db.collection.drop():删除集合。
4、文档间的关系(非关系型数据库)
-
一对一:(one to one)在MongoDB 可以通过内嵌文档的形式来体现出一对一的关系。
-
一对多:(one to many) / 多对一(many to one) 也可以通过内嵌文档的方式来映射一对多的关系
- 多对多:(many to many)
5、Sort和投影
- 查询文档是,默认情况下是按照_id的值进行排序(升序)
- sort () 可以用来指定文档的排序的规则,sort()需要传递一个对象来指定排序规则。
- 例如:db.stus.find({}).sort({字段:1}),若是正 1 表示升序,降序 -1
- limit skip sort 可以任意的顺序进行调用
- 在查询时,可以在第二个参数的位置来设置查询结果的 投影:**db.stus.find({},(name:1._id:0))**这个就表示只显示名字,默认情况下如果不加上_id:0的话是会显示ID的。
6、Mongose
- 可以为文档创建一个模式结构(Schema)。
- 可以为模型中的对象/文档进行验证。
- 数据可以通过类型转换为对象模型。
- 可以使用中间件来应用业务逻辑挂钩。
- 比Node原生的MongoDB驱动更容易。
6.1、mongoose中为我们提供几个新的对象
- Schema(模式对象):Schema对象定义约束了数据库中的文档结构
- Model:Model对象作为集合中的所有文档的表示,相当于MongoDB数据库中的集合collection
- Document:Document表示集合中具体文档,相当于集合中的一个具体文档
6.2、安装测试mongoose
mongoose文档地址:mongoose文档
- 创建一个目录以及一个package.json文件
- 若是出现一下错误:需要把上面的目录名字改掉,不能是mongoose,还有就是把package.json文件里面的name也改掉。
- 安装成功后
- 若是成功项目中会有对应的目录导入
6.21、在项目中引入mongoose
var mongoose = require("mongoose");
6.22、连接MongooDB数据库
//官网示例:
const mongoose = require('mongoose');//项目中引入mongoose
mongoose.connect('mongodb://localhost:27017/test', {
useNewUrlParser: true});
const Cat = mongoose.model('Cat', {
name: String });
const kitty = new Cat({
name: 'Zildjian' });
kitty.save().then(() => console.log('meow'));
创建一个js文件,将上面的代码作相应的修改写入,然后运行。如下
//在这里插入代码片
var mongoose = require('mongoose');//项目中引入mongoose
mongoose.connect('mongodb://localhost:27017/mongoose_test', {
useNewUrlParser: true});
mongoose.connection.once("open",function(){
console.log("数据库连接成功")
});
若是项目不能运行js文件,请先安装Node.js以及在idea中安装Node.js插件即可,我的另一篇文章中也有详细的安装教程。
–监听MongoDB数据库的连接状态
- 在mongoose对象中,有一个属性叫做connection,该对象表示的就是数据库连接通过监视该对象的状态,可以来监听数据监控的连接与断开。
- 数据库连接成功的时间mongoose.connection.once(“open”,function(){}); /数据库断开的事件 mongoose.connection.once(“close”,function(){});
6.23、断开数据库连接:mongoose.disconnect()
6.3、Schema和Model
在项目中创建另外一个js文件,用以测试。
- mongoose_demo.js
-Schema:官网示例
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var blogSchema = new Schema({
title: String, // String is shorthand for {type: String}
author: String,
body: String,
comments: [{
body: String, date: Date }],
date: {
type: Date, default: Date.now },
hidden: Boolean,
meta: {
votes: Number,
favs: Number
}
});
- model:官方示例
mongoose.model(modelName, schema):
var Blog = mongoose.model('Blog', blogSchema);
// ready to go!
- 文件内容:
var mongoose = require('mongoose');//项目中引入mongoose
mongoose.connect('mongodb://localhost:27017/mongoose_test', {
useNewUrlParser: true});
mongoose.connection.once("open",function(){
console.log("数据库连接成功")
});
//将mongoose.Schema 赋值给一个变量
var Schema = mongoose.Schema;
//创建 Schema(模式)对象
var stuSchema = new Schema({
name:String,
age:Number,
gender:{
type:String,
default:"female"
},
address:String
});
//通过Schema来创建Model
//Model代表的是数据库的集合,通过Model才能对数据库进行操作
//mongoose.model(modelName,schema);
//modelName 就是要映射的集合名,mongoose会自动将集合名变为复数
var StuModel = mongoose.model("student",stuSchema);
//创建完model后依然不能再数据库中创建,因为需要创建文档
//向数据库中插入一个文档
//StuModel.create(doc,function(err){});
StuModel.create({
name:"孙悟空",
age: 18,
gender:"male",
address: "花果山"
},function(err){
if (!err){
console.log("插入成功!!!");
}
});
- 点击运行,然后就会有相关数据!
- 查看数据库,已经创建了相关的数据
6.4、Model的方法
相关方法:官方文档Model方法
有了Model,我们就可以来对数据进行增删改查的操作了
- 创建
Model.create(doc(s),(callback)),用来创建一个或者多个文档并添加到数据库中- 参数:
doc(s):可以使一个文档对象,也可以是一个文档对象的手机开
callback: 当操作完成以后跳跃的回调函数
- 参数:
// pass a spread of docs and a callback
Candy.create({
type: 'jelly bean' }, {
type: 'snickers' }, function (err, jellybean, snickers) {
if (err) // ...
});
// pass an array of docs
var array = [{
type: 'jelly bean' }, {
type: 'snickers' }];
Candy.create(array, function (err, candies) {
if (err) // ...
var jellybean = candies[0];
var snickers = candies[1];
// ...
});
// callback is optional; use the returned promise if you like:
var promise = Candy.create({
type: 'jawbreaker' });
promise.then(function (jawbreaker) {
// ...
})
- 查询
Model.find/findOne/findMany(conditions,[projection],[options].[callback]);
-参数
conditions:查询条件
projection:投影,需要获取到的字段
- 两种方式(需要name ,不要id 的示例)
{name:1,_id:0}
“name -_id”
options:查询选项(skip limit) 设置跳过的数量或者限制显示多少个
callback:回调函数,查询结果会通过回电函数返回,回调函数必须传,如果不传回调函数,压根就不会查询。
// named john and at least 18
MyModel.find({
name: 'john', age: {
$gte: 18 }});
// executes, passing results to callback
MyModel.find({
name: 'john', age: {
$gte: 18 }}, function (err, docs) {
});
// executes, name LIKE john and only selecting the "name" and "friends" fields
MyModel.find({
name: /john/i }, 'name friends', function (err, docs) {
})
// passing options
MyModel.find({
name: /john/i }, null, {
skip: 10 })
// passing options and executes
MyModel.find({
name: /john/i }, null, {
skip: 10 }, function (err, docs) {
});
// executing a query explicitly
var query = MyModel.find({
name: /john/i }, null, {
skip: 10 })
query.exec(function (err, docs) {
});
// using the promise returned from executing a query
var query = MyModel.find({
name: /john/i }, null, {
skip: 10 });
var promise = query.exec();
promise.addBack(function (err, docs) {
});
- 修改
Model.find/One/Many(conditions,[projection],[options].[callback]);
-参数
conditions:查询条件
dos:修改后的对象
options:配置参数
callback:回调函数,
MyModel.update({
age: {
$gt: 18 } }, {
oldEnough: true }, fn);
const res = await MyModel.update({
name: 'Tobi' }, {
ferret: true });
res.n; // Number of documents that matched `{ name: 'Tobi' }`
// Number of documents that were changed. If every doc matched already
// had `ferret` set to `true`, `nModified` will be 0.
res.nModified;
- 删除
Model.remove(conditions,[callback])
Model.delete/deleteManty(conditions,[callback])
Character.deleteOne({
name: 'Eddard Stark' }, function (err) {
});
6.5、document的方法
- Document 和 集合中的文档一一对应,Document是Model的实例,通过Model查询到结果都是Document
仅仅是创建一个对象,并没有插入是数据库。
相关方法:document方法
6.6、Model的模块化
- 新建一个js文件,定义一个模块。
var mongoose = require('mongoose');//项目中引入mongoose
mongoose.connect('mongodb://localhost:27017/mongoose_test', {
useNewUrlParser: true});
mongoose.connection.once("open",function(){
console.log("数据库连接成功")
});
- 新建一个文件,用来定义Schmea
var mongoose = require('mongoose');//项目中引入mongoose
var Schema = mongoose.Schema;
var stuSchema = new Schema({
name:String,
age:Number,
gender:{
type:String,
default:"female"
},
address:String
});
var StuModel = mongoose.model("student",stuSchema);
model.exports = StuModel; //将其暴露出去,方便调用
- 新建一个js文件,启动mongoose
require("上个文件的相对路径");
var Student = require("student文件路径");
到此为止,MongoDB的简单入门就已经讲完。