热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Node.js系列使用MongoDB数据库

#前言作为还在漫漫前端学习路上的一位自学者。我以学习分享的方式来整理自己对于知识的理解,同时也希望能够给大家作为一份参考。希望能够和大家共同进步,如有任何纰漏的话,希望大家多多指正

# 前言

作为还在漫漫前端学习路上的一位自学者。我以学习分享的方式来整理自己对于知识的理解,同时也希望能够给大家作为一份参考。希望能够和大家共同进步,如有任何纰漏的话,希望大家多多指正。感谢万分!

在这一节让我们开始学着在 Node.js 中使用 MongoDB 数据库.

# 什么是 MongoDB

『 MongoDB 』 是由 C++ 语言编写的, 基于分布式文件存储的数据库. 属于 NoSql (非关系型数据库) 的一种, 旨在为 WEB 应用提供可扩展的高性能数据存储解决方案.

MongoDB 将数据存储为一个文档,数据结构由键值对 key:value 组成. MongoDB 文档类似于 JSON 对象. 字段值可以包含其他文档,数组及文档数组.

下面就是一个 MongoDB 文档 (document) 示例:

{
"name": "Garrik",
"age": 21,
"gender": "Male",
"job": "Frontend Developer"
}

## 关系型数据库 & 非关系型数据库

前面说到 MongoDB 是属于非关系型数据库的一种, 那么什么是关系型? 什么是非关系型?

关系型数据库 』以 “行” 和 “列” 组成的 “二维表格” 形式来存储数据, 二维表格简称为称为表, 表又组成了数据库. 之所以称之为关系型数据库, 因为表与表之间采用了现实世界中实体 (entitiy) 与实体 (entitiy) 之间的关系模型. 表中存储格式化结构的数据,每个 “元组”(可以理解为二维表中的一行)的字段组成都是一样的. 即使不是每个元组都需要所有的字段,但数据库会为每个元组都分配所有的字段,这样的结构可以便于表与表之间进行连接等操作. 比较常见的关系型数据库有 Oracle, MySQL 等.

非关系数据库 』以 “键值对” 存储,它的结构不固定,每一个元组可以有不一样的字段,可以根据需要增加或减少一些自己的键值对,不会局限于固定的结构. 数据之间的关联性不强制, 使用起来要比关系型数据库更加灵活, 性能也有提升. 比较常见的非关系型数据库有 MongoDB, Redis 等

# MongoDB 基础概念

在具体讲如何使用 MongoDB 之前, 我要先介绍一些基本概念.

## 文档 (document)

文档 』是一组 “键值对” 的有序集合. 是 MongoDB 的核心概念. 文档的数据结构被称为 BSON, 是一种类似于 JSON 的二进制形式的存储格式. 下面是一个文档示例:

{
"name": "Garrik",
"age": 21
}

"name""age" 是这个文档的 “键” (key), "Garrik"21 是 “值” (value)

文档中的值可以是多种不同的数据类型. 在一个集合中各个文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型.

MongoDB 区分类型和大小写. 例如,下面的两个文档是不同的:

{"foo" : 3}
{"Foo" : "3"}

在给文档的 “键” 命名时还需要注意: 文档的键必须是字符串 键不能含有 \0 (空字符)。这个字符用来表示键的结尾 .$ 有特别的意义,只有在特定环境下才能使用 以下划线 _开头的键是保留的 (不是严格要求的) * 一个文档内不能有重复的键

## 集合 (collection)

集合 』就是一组文档,如果将 MongoDB 中的一个文档比喻为关系型数据库中的一行,那么一个集合就相当于一张表. 集合存在于数据库中,当第一个文档插入时,集合就会被创建. 集合没有固定的结构,一个集合里面的文档可以是各式各样的,这被称为 『 动态模式 』

下面是一个集合示例:

{
"site": "www.baidu.com",
"name": "百度"
}
{
"site": "www.google.com",
"name": "Google",
"query": {
"search": "前端开发"
}
}
{
"site": "www.zhihu.com",
"name": "知乎",
"username": "罐装汽水_Garrik"
}

虽然 MongoDB 对集合中的文档类型没有要求, 但通常情况下我们插入集合的数据都会有一定的关联性. 这样会降低查询特定文档的复杂度, 并且提升查询速度.

集合命名时需要注意: 集合名不能是空字符串。 集合名不能含有 \0(空字符),这个字符表示集合名的结尾。 集合名不能以 system. 开头,这是为系统集合保留的前缀。 用户创建的集合名字不能含有保留字符 $

## 数据库 (database)

数据库 』由多个集合组成. 在 MongoDB 中可以建立多个数据库。每个数据库都有独立的权限,即便是在磁盘上,不同的数据库也放置在不同的文件中。按照经验,我们将有关一个应用程序的所有数据都存储在同一个数据库中。要想在同一个 MongoDB 服务器上存放多个应用程序或者用户的数据,就需要使用不同的数据库。

MongoDB 的默认数据库为 "db",该数据库存储在 data 目录中。

数据库名可以是满足以下条件的任意 UTF-8 字符串: 不是空字符串 不得含有 空格.$/\\0 (空字符) 数据库名区分大小写, 推荐全部小写 最多 64 字节

数据库最终会变成文件系统里的文件,而数据库名就是相应的文件名

文档, 表单, 数据库之间的关系如下图:

《Node.js 系列 - 使用 MongoDB 数据库》
《Node.js 系列 - 使用 MongoDB 数据库》

# 安装 MongoDB & 可视化工具

这篇文章我不想过多讲安装步骤, 大家可以自行去查阅方法.

Windows 平台安装 MongoDBwww.runoob.com《Node.js 系列 - 使用 MongoDB 数据库》
Mac OSX 平台安装 MongoDBwww.runoob.com《Node.js 系列 - 使用 MongoDB 数据库》

为了更方便的管理 MongoDB 数据库, 我推荐使用 Studio 3T 可视化工具.

The MongoDB GUI, IDE & Client for Professional Devs – Studio 3Tstudio3t.com《Node.js 系列 - 使用 MongoDB 数据库》

使用方法可参照下面链接内容:

MongoDB可视化工具Studio 3T的使用blog.csdn.net《Node.js 系列 - 使用 MongoDB 数据库》

# 在 Node.js 中使用 MongoDB

MongoDB Driver API for Node.jsmongodb.github.io

想要在 Node.js 中使用 MongoDB, 要先安装 mongodb 模块, 具体步骤不赘述. 在 Node.js 中使用之前, 还需要先在命令行中用 mongod 指令运行 MongoDB 服务器.

以下代码适用于 mongodb 模块 3.x 版本

## 连接数据库

要想连接 MongoDB 数据库, 我们要先创建一个 MongoDB 客户端并且连接上 MongoDB 服务器. 之后在此连接之上创建数据库实例.

// 引入模块 const MongoClient = require('mongodb').MongoClient;
// MongoDB 服务器的地址 const url = 'mongodb://localhost:27017';
// 目标数据库的名字 const dbname = 'mydb';
// 创建 MongoDB 客户端 const client = new MongoClient(url);
// 让客户端连接上服务器 client.connect(function(err) {
if (err) throw err;
console.log("成功连接到 MongoDB 服务器!");
// 创建数据库实例 const db = client.db(dbname);
// 断开连接 client.close();
});

## 插入文档

要想向一个特定的集合插入文档, 首先我们用 db.collection 方法去获取目标集合的实例对象. 该方法第一个参数为集合的名字. 如果用这个名字的集合之前不存在, 它会自动帮你创建.

之后我们用刚刚获得的集合实例的 insertManyinsertOne 方法来向集合插入文档.

区别是: insertOne 用以插入单个文档, 第一个参数为文档对象 insertMany 用以插入多个文档, 第一个参数为由文档对象组成的数组

这两个方法的最后一个参数都为回调函数. 回调函数的第一个参数为错误信息, 第二个为处理结果

假如说我们现在要向 usersInfo 集合插入用户信息, 代码如下:

client.connect(function(err) {
if (err) throw err;
const db = client.db(dbname);
// 获取 'usersInfo' 集合的实例对象. const collection = db.collection('usersInfo');
// 插入单个用户的信息 collection.insertOne({
name: "Garrik",
date_of_birth: new Date("1997-06-04")
}, function(err, result) {
if (err) throw err;
client.close();
})
});

## 查询全部文档

如果我们想查询一个集合下的全部文档, 我们可以使用集合实例的 find 方法. 该方法的第一个参数为查询条件对象, 如果传入一个空对象 {} 则表示查询全部文档.

client.connect(function(err) {
if (err) throw err;
const db = client.db(dbname);
// 获取 'usersInfo' 集合的实例对象. const collection = db.collection('usersInfo');
// 查询集合下的所有文档, 然后用 toArray 转换成数组 collection.find({}).toArray(function(err, result) {
if (err) throw err;
console.log(result);
client.close();
});
});

## 查询特定文档

前面说集合实例的 find 方法的第一个参数为查询条件对象. 想要查找特定文档的前提是知道怎么写查询条件对象.

首先, 平时最常用的查询是找到有特定 “键值对” 的文档. 比如找到 “文档中有 name 键, 且它的值为 小明“. 这个查询写成查询条件对象是: {'name':'小明'}. 假如要查询的文档在 usersInfo 集合下, 在 Node.js 的代码就为:

// 客户端连接上服务器 client.connect(function(err) {
if (err) throw err;
console.log("成功连接到 MongoDB 服务器!");
// 创建数据库实例 const db = client.db(dbname);
//查询 'name' 等于 '小明' 的文档 db.collection('usersInfo').find({ 'name': '小明' }).toArray((err, array) => {
if (err) throw err;
// 打印出匹配到的文档 console.log(array);
// 关闭客户端 client.close();
})
});

如果再想加一条 gender 键的值 等于 male. 那查询条件对象就为 {'name':'小明', 'gender':'male'} 查询条件对象中各个条件是 AND 的关系. 也就是只匹配 name 键的值等于 小明, 且 gender 键的值为 male 的文档.

假如集合中的文档有如下:

{ "_id" : ObjectId("5bd1e7df8a5c0550f4722b01"), "name" : "小明", "gender" : "male" }
{ "_id" : ObjectId("5bd1e7e28a5c0550f4722b02"), "name" : "小明", "gender" : "female" }
{ "_id" : ObjectId("5bd1e7e88a5c0550f4722b03"), "name" : "小红", "gender" : "female" }
{ "_id" : ObjectId("5bd1e7f48a5c0550f4722b04"), "name" : "小王", "gender" : "male" }

那么执行上面代码匹配到的为:

{ "_id" : ObjectId("5bd1e7df8a5c0550f4722b01"), "name" : "小明", "gender" : "male" }

## 数值比较

上面的查询条件都是精确匹配, 也就是匹配文档中某个键的值是否等于多少. 平时常用的另一个查询是范围比较. 也就是 <, >, <=, >=, !=. 它们对应的 MongoDB 关键字为 $lt, $gt, $lte, $gte.

比如要匹配 age 键的值小于 60, 那么查询条件对象为 {'age': {$lt:60}}.

如果在小于 60 的同时还要大于 18, 那就是 {'age': {$lt:60, $gt:18}}.

## OR 查询

MongoDB 中有两种方式进行 OR 查询: $in 关键字可以查询一个键的多个值 $or 可以用于多个键值对.

比如我们要查 name 键的值为 小明 或者 小红 的文档. 用 $in 的话, 文档查询对象为 {'name': {$in: ['小明', '小红']}}; 用 $or 的话, 文档查询对象为 {$or:[{'name':'小明'}, {'name':'小红'}]}

但如果我们要查 name 键的值为 小明小红, 或者 gender 键的值为 male 的文档的话, $in$or 结合使用会很方便. 其文档查询对象为 {$or:[{'name':{$in:['小明','小红']}}, {'gender':'male'}]}

## 更新文档

使用集合实例的 updateOneupdateMany 方法可以更新文档. 它们的第一个参数为查询对象, 用来匹配到需要更新的文档. 第二个参数为更新对象, 也就是要应用于文档上的更新内容. 最后一个参数为回调函数, 回调函数第一个参数为错误信息, 第二个为操作结果. 这两个方法的区别是 updateOne 只更新匹配到的第一个文档, updateMany 更新所有匹配到的文档.

比如我们要更新 name 键的值为 小明 的文档的 age 键为 22. Node.js 代码如下: (注意更新对象里面的 $set 关键字)

// 客户端连接上服务器 client.connect(function(err) {
if (err) throw err;
console.log("成功连接到 MongoDB 服务器!");
// 创建数据库实例 const db = client.db(dbname);
//查询 'name' 等于 '小明' 的文档, 然后更新 `age` 键 db.collection('usersInfo').updateOne({ 'name': '小明' }, { $set: { 'age': 22 } }, function(err, result) {
if (err) throw err;
console.log(result);
// 关闭客户端 client.close();
});
});

## 删除文档

想要删除一个文档可以用 deleteOnedeleteMany 方法. 第一参数为查询对象, 最后一个参数为回调函数.

比如我们要删除 name小明 的第一个文档. Node.js 代码如下:

// 客户端连接上服务器 client.connect(function(err) {
if (err) throw err;
console.log("成功连接到 MongoDB 服务器!");
// 创建数据库实例 const db = client.db(dbname);
//删除 'name' 等于 '小明' 的第一条文档 db.collection('usersInfo').deleteOne({ 'name': '小明' }, function(err, result) {
if (err) throw err;
console.log(result);
// 关闭客户端 client.close();
});
});

&#x1f606; 好啦,今天的分享就告一段落啦。在下一期我会手把手演示如何实现一个连接了 MongoDB 数据库的 Todo List 页面程序.

罐装汽水Garrik:Node.js 系列 &#8211; [实战] TODO 单页面程序zhuanlan.zhihu.com《Node.js 系列 - 使用 MongoDB 数据库》

如果喜欢的话就点个关注吧!O(∩_∩)O 谢谢各位的支持&#x2757;&#xfe0f;


推荐阅读
  • 本文深入探讨了NoSQL数据库的四大主要类型:键值对存储、文档存储、列式存储和图数据库。NoSQL(Not Only SQL)是指一系列非关系型数据库系统,它们不依赖于固定模式的数据存储方式,能够灵活处理大规模、高并发的数据需求。键值对存储适用于简单的数据结构;文档存储支持复杂的数据对象;列式存储优化了大数据量的读写性能;而图数据库则擅长处理复杂的关系网络。每种类型的NoSQL数据库都有其独特的优势和应用场景,本文将详细分析它们的特点及应用实例。 ... [详细]
  • 从0到1搭建大数据平台
    从0到1搭建大数据平台 ... [详细]
  • 在CentOS 7环境中安装配置Redis及使用Redis Desktop Manager连接时的注意事项与技巧
    在 CentOS 7 环境中安装和配置 Redis 时,需要注意一些关键步骤和最佳实践。本文详细介绍了从安装 Redis 到配置其基本参数的全过程,并提供了使用 Redis Desktop Manager 连接 Redis 服务器的技巧和注意事项。此外,还探讨了如何优化性能和确保数据安全,帮助用户在生产环境中高效地管理和使用 Redis。 ... [详细]
  • Python 数据可视化实战指南
    本文详细介绍如何使用 Python 进行数据可视化,涵盖从环境搭建到具体实例的全过程。 ... [详细]
  • MongoDB核心概念详解
    本文介绍了NoSQL数据库的概念及其应用场景,重点解析了MongoDB的基本特性、数据结构以及常用操作。MongoDB是一个高性能、高可用且易于扩展的文档数据库系统。 ... [详细]
  • 本文详细介绍了使用 Python 进行 MySQL 和 Redis 数据库操作的实战技巧。首先,针对 MySQL 数据库,通过 `pymysql` 模块展示了如何连接和操作数据库,包括建立连接、执行查询和更新等常见操作。接着,文章深入探讨了 Redis 的基本命令和高级功能,如键值存储、列表操作和事务处理。此外,还提供了多个实际案例,帮助读者更好地理解和应用这些技术。 ... [详细]
  • 在一个整型数组中,除了两个数字只出现一次外,其他所有数字都出现了两次。编写一个程序来找出这两个只出现一次的数字。 ... [详细]
  • 本文探讨了 TypeScript 中泛型的重要性和应用场景,通过多个实例详细解析了泛型如何提升代码的复用性和类型安全性。 ... [详细]
  • 本文讨论了在 Oracle 10gR2 和 Solaris 10 64-bit 环境下,从 XMLType 列中提取数据并插入到 VARCHAR2 列时遇到的性能问题,并提供了优化建议。 ... [详细]
  • 包含phppdoerrorcode的词条 ... [详细]
  • Ihavetwomethodsofgeneratingmdistinctrandomnumbersintherange[0..n-1]我有两种方法在范围[0.n-1]中生 ... [详细]
  • MySQL Decimal 类型的最大值解析及其在数据处理中的应用艺术
    在关系型数据库中,表的设计与SQL语句的编写对性能的影响至关重要,甚至可占到90%以上。本文将重点探讨MySQL中Decimal类型的最大值及其在数据处理中的应用技巧,通过实例分析和优化建议,帮助读者深入理解并掌握这一重要知识点。 ... [详细]
  • 本文详细介绍了在 Oracle 数据库中使用 MyBatis 实现增删改查操作的方法。针对查询操作,文章解释了如何通过创建字段映射来处理数据库字段风格与 Java 对象之间的差异,确保查询结果能够正确映射到持久层对象。此外,还探讨了插入、更新和删除操作的具体实现及其最佳实践,帮助开发者高效地管理和操作 Oracle 数据库中的数据。 ... [详细]
  • 本文介绍了如何在 Windows 系统上利用 Docker 构建一个包含 NGINX、PHP、MySQL、Redis 和 Elasticsearch 的集成开发环境。通过详细的步骤说明,帮助开发者快速搭建和配置这一复杂的技术栈,提升开发效率和环境一致性。 ... [详细]
  • 第二章:Kafka基础入门与核心概念解析
    本章节主要介绍了Kafka的基本概念及其核心特性。Kafka是一种分布式消息发布和订阅系统,以其卓越的性能和高吞吐量而著称。最初,Kafka被设计用于LinkedIn的活动流和运营数据处理,旨在高效地管理和传输大规模的数据流。这些数据主要包括用户活动记录、系统日志和其他实时信息。通过深入解析Kafka的设计原理和应用场景,读者将能够更好地理解其在现代大数据架构中的重要地位。 ... [详细]
author-avatar
_陈灵宝互粉号2
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有