原生MongoDB
首先需要下载mongodb包npm i mongodb -S
连接数据库
// 客户端
const MongoClient = require('mongodb').MongoClient;
// 连接URL
const url = 'mongodb://localhost:27017';
// 数据库名
const dbName = 'test';
// 创建客户端
const client = new MongoClient(url,{useNewUrlParser: true});
// 2.获取数据库
const db = client.db('dbName');
// 3.获取集合(表)
const fruits = db.collection('fruits');插入数据
fruits.insertOne({name: `水果${i+1}`, price: i*5})await books.insertMany([
{
title: 'MongoDB Overview',
description: 'MongoDB is no sql database',
by_user: 'runoob.com',
url: 'http://www.runoob.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
},
{
title: 'NoSQL Overview',
description: 'No sql database is very fast',
by_user: 'runoob.com',
url: 'http://www.runoob.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 10
},
{
title: 'Neo4j Overview',
description: 'Neo4j is no sql database',
by_user: 'Neo4j',
url: 'http://www.neo4j.com',
tags: ['neo4j', 'database', 'NoSQL'],
likes: 750
}
])删除数据
await fruits.deleteOne({price: 50})await fruits.deleteMany();更改数据
await fruits.updateOne({name: '水果2'}, {$set: {name: '水果一'}});查询数据
查询所有
await fruits.find().toArray();选定返回字段
db.inventory.find( { status: "A" }, { item: 1, status: 1 } )
// SELECT _id, item, status from inventory WHERE status = "A"条件查询
await fruits.find({name: '水果3', price: 20}).toArray();OR AND 运算符
// AND find() 方法可以传入多个键(key),每个键(key)以逗号隔开,即常规 SQL 的 AND 条件
r = await fruits.find({name: '水果3', price: 20}).toArray();
// OR
r = await fruits.find({
$or: [
{name: '水果3'},
{name: '水果4'}
]
}).toArray()// OR和AND结合r = await fruits.find({price: {$lte : 30}, $or: [{name: '水果3'},{name: '水果4'},{name: '水果9'}]}).toArray()模糊查询(正则)
// 模糊查询 使用正则表达式进行模糊查询
r = await fruits.find({name: /水果/}).toArray();
r = await fruits.find({name: /^水/}).toArray();
r = await fruits.find({name: /3$/}).toArray();条件运算符
/**
* 条件操作符
* $gt >
* $lt <
* $gte >=
* $lt <=
*/
r = await fruits.find({price: {$gt : 40}}).toArray()
r = await fruits.find({price: {$gt: 20, $lt: 40}}).toArray()分页查询
/**
* 分页查询
* limit() 读取指定数量的数据记录
* skip() 跳过指定数量的数据(偏移量)
*/
r = await fruits.find().skip(3).limit(5).toArray();排序
/** * 排序 * sort()方法 1升序 -1降序 */ r = await fruits.find().sort({price: -1}).toArray();聚合
/**
* 聚合函数
* $sum 计算总数
* $avg 计算平均值
* $min 计算最小值
* $max 计算最大值
*/
const books = db.collection('books');
await books.insertMany([
{
title: 'MongoDB Overview',
description: 'MongoDB is no sql database',
by_user: 'runoob.com',
url: 'http://www.runoob.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
},
{
title: 'NoSQL Overview',
description: 'No sql database is very fast',
by_user: 'runoob.com',
url: 'http://www.runoob.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 10
},
{
title: 'Neo4j Overview',
description: 'Neo4j is no sql database',
by_user: 'Neo4j',
url: 'http://www.neo4j.com',
tags: ['neo4j', 'database', 'NoSQL'],
likes: 750
}
])
// select by_user as _id, count(*) as num_tutorial from books group by by_user
r = await books.aggregate([
{
$group: {
_id: '$by_user',
num_tutorial: { $sum: 1 }
}
}
]).toArray();
// select by_user as _id, count('likes') as num_tutorial from books group by by_user
r = await books.aggregate([
{
$group: {
_id: '$by_user',
num_tutorial: { $sum: '$likes' }
}
}
]).toArray();联合查询($lookup)
/**
* 联合查询
* $lookup 左连接
*/
const orders = await db.collection('orders');
await orders.insertOne({_id: 1, product_id: 154, status: 1});
const products = await db.collection('products');
await products.insertMany([
{ _id: 154, name: '笔记本电脑' },
{ _id: 155, name: '耳机' },
{ _id: 156, name: '台式电脑' }
])
r = await orders.aggregate([
{
$lookup: {
from: 'products', // 右集合
localField: 'product_id', // 左集合join字段
foreignField: '_id', // 右集合join字段
as: 'orderdetails' // 新生成字段(类型array)
}
}
]).toArray();
console.log('查询所有数据: ', JSON.stringify(r));ORM Mongoose
下载mongoose包npm i mongoose -S
连接数据库
const mongoose = require('mongoose')
// 1. 连接
mongoose.connect('mongodb://localhost:27017/test', { useNewUrlParser: true });
const conn = mongoose.connection;
conn.on('error', () => console.error('连接数据库失败'));定义Schema(Table)
conn.once('open', async () => { // 2. 定义一个Schema - Table const Schema = mongoose.Schema({ category: String, name: String });
})创建数据模型
const Model = mongoose.model('fruit', Schema);新增数据
// 4. 创建,create返回Promise
let r;
r = await Model.create({
category: '温带水果',
name: '苹果',
price: 5
});
console.log('插入数据: ', r);更改数据
// 6. 更新 updateOne 返回Query
r = await Model.updateMany({name: '苹果'}, {$set: {name: '芒果'}});
console.log('修改成功: ', r);删除数据
// 7. 删除 deleteOne返回Query
r = await Model.deleteMany({name: '芒果'});查询数据
// 5. 查询数据 find返回Query,它实现then和catch,可以当Promise使用
// 如果需要返回Promise,调用exec()
r = await Model.find();
console.log('查询数据:', r);定义字段 Schema
const blogSchema = mongoose.Schema({
title: { type: String, required: [true, '标题为必填项'] }, // 定义校验规则
author: String,
body: String,
comments: [{ body: String, date: Date }], // 定义对象数组
date: { type: Date, default: Date.now }, // 指定默认值
hidden: Boolean,
meta: {
// 定义对象
votes: Number,
favs: Number
}
});定义多个索引
// 定义多个索引 blogSchema.index({title: 1, author: 1, date: -1}); const blogModel = mongoose.model('blog', blogSchema); const blog = new blogModel({ title: 'nodejs持久化', author: 'jerry', body: '这是关于Node.js博客' }) r = await blog.save(); console.log('新增blog ', r)定义实例方法
抽象出常用方法便于复用
// 定义实例方法
blogSchema.methods.findByAuthor = function(auth) {
return this.model('blog').find({author: this.author}).exec();
}
// 获取模型实例
const BlogModel = mongoose.model('blog', blogSchema);
const blog = new BlogModel({
title: 'nodejs持久化',
author: 'jerry',
body: '这是关于Node.js博客'
});
// 调用方法
r = await blog.findByAuthor();
console.log('findAuthor', r);静态方法
// 静态方法
blogSchema.statics.findByAuthor = function(author){
return this.model('blog').find({author}).exec();
}
// 获取模型实例
const BlogModel = mongoose.model('blog', blogSchema);
r = await BlogModel.findByAuthor('jerry');
console.log('findByAuthor: ', r)虚拟属性
// 虚拟属性 blogSchema.virtual('commentsCount').get(function() { return this.comments.length; }) // 获取模型实例 const blog = mongoose.model('blog', blogSchema); r = await blog.findOne({author: 'jerry'}); console.log('blog留言数: ', r.commentsCount);