简介
- MongoDB 是一种文档数据库
- 为快速开发互联网Web应用而设计的数据库系统
- 设计目标是极简、灵活、作为Web应用栈的一部分
- 数据模型是面向文档的,所谓文档是一种类似于JSON的结构(BSON)
三个概念
- 数据库:一个仓库,可以存放集合
- 集合:类似于数组,可以存放文档
- 文档:文档数据库中的最小单位,存储与操作的内容
数据库和集合都不需要手动创建,如果文档所在的集合或数据库不存在,会自动创建
安装与使用
- 安装
- 配置环境变量
- cmd打开一个窗口:
mongod --dbpath 数据库路径 --port 端口号
启动服务 - 再打开一个窗口:
mongo
- 设置MongoDB为系统服务:参考官网配置
https://blog.csdn.net/weixin_48167124/article/details/126580851
语法
常用指令
// 显示当前所有的数据库
show databases;
show dbs;
// use 数据库名 进入到指定的数据库
use lmy;
// 查看当前所处的数据库
db;
// 显示当前数据库中所有的集合
show collections;
向集合中插入文档
// db.<collection名>.insert() 可以插入一个也可以插入多个
db.books.insert({name:"默读", author:"Priest", characters:"骆闻舟&费渡"});
// { "_id" : ObjectId("61666d5205f78314fe795a4f"), "name" : "默读", "author" : "Priest", "characters" : "骆闻舟&费渡" }
// 如果向集合中插入文档时没有指定_id属性,数据库会自动添加,该属性作为文档的唯一标识,也可以指定该属性的值,但是要确保唯一性
ObjectId(); // ObjectId("6166b7d3cb7c4809891b2e7e")
db.books.insert([
{name:"铜钱龛世", author:"木苏里", characters:"玄悯&薛闲"},
{name:"我喜欢你的信息素", author:"引路星", characters:"路星辞&段佳衍"}
]);
// db.<collection名>.insertOne()
// db.<collection名>.insertMany()
查询文档
// db.<collection名>.find() 返回值是个数组,可以索引调用
db.books.find()[0];
db.books.find({author : "Priest")})[0];
// db.<collection名>.findOne() 符合条件的第一个文档对象
// db.<collection名>.find().count() 统计查询到的文档个数
db.books.find().count();
修改文档
// db.<collection名>.update(查询条件,新对象) 默认情况下会使用新对象替换旧对象
db.books.update({name:"默读"}, {author: "P甜甜"});
/*
如果只修改指定的属性,需要使用修改操作符
$set 可以用来修改文档中的指定属性,也可以新增属性
$unset 可以用来删除文档中的指定属性
*/
db.books.update(
{name:"铜钱龛世"},
{
$set: {
author: "MuSuLi",
gender: "female"
}
}
);
db.books.update(
{name:"铜钱龛世"},
{
$unset: {
gender: "female"
}
}
);
/*
db.<collection名>.updateMany()
update默认情况下只会修改一个,该方法会修改多个
如果update想要修改多个,可以传入第三个参数{multi: true}
db.<collection名>.updateOne()
db.<collection名>.replaceOne()
*/
删除文档
/*
db.<collection名>.remove()
删除符合条件的所有文档
db.<collection名>.deleteOne()
db.<collection名>.deleteMany()
*/
db.characters.remove({gender: "男"});
db.characters.remove({gender: "男"}, true); // 只删除一个
db.characters.remove({}) // 删除集合中的所有文档
db.characters.drop() // 删除集合,如果该集合是数据库中的最后一个集合,那么数据库也会被删除
db.dropDatabase() // 删除数据库
实例:
{
_id: ObjectId("6168e2cc167f5667a6c9c26d"),
username: "sunwukong",
hobby: {
cities: ["beijing", "shanghai", "shenzhen"],
movies: ["sanguo", "hero"],
},
};
{
_id: ObjectId("6168e31b167f5667a6c9c26e"),
username: "tangseng",
hobby: { movies: ["A Chinese Odyssey", "King of comedy"] },
};
// 查找movies包含hero的文档
db.users.find({"hobby.movies":"hero"}); // 可以匹配数组中的元素
// 向数组中追加元素
db.users.update({username:"tangseng"},{$push:{"hobby.movies":"Interstellar"}}); // $addToSet 也可以追加元素,但是不会追加重复元素
// 增加20000条数据
for(var i=1;i<=20000;i++) {
db.numbers.insert({num:i});
}
// 下面的方式执行快
var list = [];
for(var i=1;i<=20000;i++) {
list.push({num:i})
}
db.numbers.insert(list);
// 查询num大于5000的文档
db.numbers.find({num:{$gt:5000}}); // $lt $gte $lte $ne $eq
// 查询num大于40小于50的文档
db.numbers.find({num:{$lt:50,$gt:40}});
// 查询前10条数据
db.numbers.find().limit(10);
// 查看第10-20条数据
db.numbers.find().skip(10).limit(10); // 分页效果 skip和limit可以换位置
// 或查询
db.books.find(
{
$or: [
{author:"Priest"},
{gender:"female"}
]
}
)
// 累加400
db.emp.updateMany({name:"dudu"},{$inc:{sal:400}});
// 查询默认按照_id进行升序排列,可以用sort指定排序规则 (1表示升序,-1表示降序)
db.emp.find().sort({sal:1, empno:-1});
// 只查询部分字段(只显示ename列,不显示id列)
db.emp.find({},{ename:1,_id:0});
mongoose
- 一个可以通过Node来操作MongoDB的模块,它对Node原生的MongoDB模块进行了进一步的优化封装,并提供了更多的功能
- 优点:
- 可以为文档创建一个模式结构(约束)
- 可以对模型中的对象/文档进行验证
- 数据可以通过类型转换转换为对象模型
- 可以使用中间件来应用业务逻辑挂钩
- 比Node原生的MongoDB驱动更容易
- mongoose提供了几个新的对象
- Schema 模式对象:约束了数据库中的文档结构
- Model:作为集中中所有文档的表示,相当于collection
- Document:表示集合中的具体文档
连接数据库
// 先下载安装 npm i mongoose
var mongoose = require("mongoose");
// 连接数据库 端口号默认为27017可以不写
// 只需要连接一次,无需每次操作都重新连接
mongoose.connect("mongodb://127.0.0.1/lmy");
// 监听数据库连接状态
mongoose.connection.once("open", function () {
console.log("数据库连接成功");
});
mongoose.connection.once("close", function () {
console.log("数据库连接断开");
});
// 断开数据库连接 一般不调用
mongoose.disconnect();
创建Schema和Model
var mongoose = require("mongoose");
mongoose.connect("mongodb://127.0.0.1/lmy");
mongoose.connection.once("open", function () {
console.log("-----------数据库连接成功-----------");
});
// 创建约束对象
var booksSchema = new mongoose.Schema({
name: String,
author: String,
characters: String,
price: {
type: Number,
default: 10,
},
});
// 创建Model
var BooksModel = mongoose.model("books", booksSchema);
插入文档
/*
Model.find(docs, [callback])
用来创建一个文档添加到数据库中
参数:
docs 可以是一个文档对象,也可以是一个文档对象的数组
callback 当操作完成以后调用的回调函数
*/
BooksModel.create(
[
{
name: "我行让我上",
author: "酱子贝",
characters: "路柏沅&简茸",
},
{
name: "唇枪",
author: "金十四钗",
characters: "虞仲夜&刑鸣",
},
],
function (err) {
// console.log(arguments); // error, 插入的文档
if (!err) {
console.log("插入成功");
}
}
);
查询文档
/*
参数:查询条件,投影,查询选项,回调函数(必传,不传不会进行查询)
Model.find(filter, [projection], [options], [callback]) 返回一个文档数组
Model.findById(id, [projection], [options], [callback]) 直接返回一个文档
Model.findOne([filter], [projection], [options], [callback]) 直接返回一个文档
*/
BooksModel.find(
{ name: "默读" },
"name author -_id",
// { skip: 2, limit: 0 },
function (err, docs) {
if (!err) {
// 通过find() 查询的结果,返回的对象就是Document,它是Model的实例
console.log(docs, docs[0] instanceof BooksModel);
}
}
);
修改文档
/*
参数:查询条件,修改后的对象,配置参数,回调函数
Model.update(filter, doc, [options], [callback]) 弃用
Model.updateOne(filter, doc, [options], [callback])
Model.updateMany(filter, doc, [options], [callback])
Model.replaceOne(filter, doc, [options], [callback])
*/
BooksModel.updateOne(
{ name: "默读" },
{ $set: { author: "一口獠牙的小甜甜" } },
function (err) {
if (!err) {
console.log("修改成功");
}
}
);
删除文档
/*
参数:查询条件,配置参数,回调函数
Model.remove(filter, [options], [callback]) 弃用
Model.deleteOne(filter, [options], [callback])
Model.deleteMany(filter, [options], [callback])
*/
BooksModel.deleteOne({ name: "我行让我上" }, function (err) {
if (!err) {
console.log("删除成功");
}
});
统计数目
/*
参数:查询条件,回调函数
Model.countDocuments(filter, [callback])
*/
BooksModel.countDocuments({ name: "唇枪" }, function (err, num) {
if (!err) {
console.log(num);
}
});
Document的方法:创建与保存
// 创建一个Document对象
var book = new BooksModel({
name: "杀破狼",
author: "Priest",
characters: "长庚&顾昀",
});
console.log(book);
// 将对象保存到数据库
book.save(function (err) {
if (!err) {
console.log("保存成功");
}
});
Document的方法:修改
BooksModel.findOne({}, function (err, doc) {
if (!err) {
// update(update, [options], [callback]) 废弃 使用updateOne, updateMany
doc.updateOne(
{ $set: { name: "某某", characters: "江添&盛望" } },
function (err) {
if (!err) {
console.log("修改成功");
}
}
);
// 也可以直接修改对象的属性然后再保存
// doc.author = "MuSuLi";
// doc.save();
}
});
Document的方法:删除
BooksModel.findOne({}, function (err, doc) {
if (!err) {
// remove([callback])
doc.remove(function (err) {
if (!err) {
console.log("删除成功");
}
});
}
});
Document的方法:其他
BooksModel.findOne({}, function (err, doc) {
if (!err) {
// get set 获取设置文档中的属性值
console.log(doc.get("name")); // 我喜欢你的信息素
doc.set("name", "路狗的千层套路");
console.log(doc.get("name")); // 路狗的千层套路
// id属性:获取_id的值
console.log(doc.id);
// toObject() 转换为普通JS对象
console.log(doc instanceof BooksModel); // true
var book = doc.toObject();
console.log(book instanceof BooksModel); // false
}
});
mongoose模块化实现
- 数据库连接模块
var mongoose = require("mongoose"); mongoose.connect("mongodb://127.0.0.1/lmy"); mongoose.connection.once("open", function () { console.log("-----------数据库连接成功-----------"); });
- Model创建模块
var mongoose = require("mongoose"); var booksSchema = new mongoose.Schema({ name: String, author: String, characters: String, price: { type: Number, default: 10, }, }); module.exports = mongoose.model("books", booksSchema);
使用
require("./conn_mongo");
var BooksModel = require("./books");
BooksModel.find({}, function (err, docs) {
if (!err) {
console.log(docs.length);
}
});