MongoDB & Redis 快速上手:NoSQL数据库操作精要

先言之

☘️随着大数据时代的到来,非关系型数据库因其灵活性和扩展性逐渐受到开发者的青睐。MongoDBRedis 作为两种非常流行的 NoSQL 数据库,各自拥有独特的特性和应用场景。MongoDB 是一款面向文档的数据库,适用于需要存储复杂数据结构的应用;而 Redis 则以其卓越的速度和内存存储能力著称,非常适合高速缓存实时数据分析

✍️本文旨在为初学者提供一份简洁明了的手册,帮助大家快速掌握 MongoDBRedis 的基本语法及常用操作。通过本指南的学习,读者将能够迅速上手这两种数据库,为实际项目开发奠定坚实的基础。

🤲本文内容均基于官方文档撰写,并附带了相应的 SQL 语法链接。我希望在为大家提供正确语法规则的同时,也能鼓励大家养成查阅官方文档的好习惯!愿初学者以此为基础,不断探索,终成大家。

MongoDB 7.0

在这里插入图片描述
官网介绍:https://www.mongodb.com/zh-cn/docs/manual/

MongoDB 是一种非常流行的 NoSQL 数据库,特别适合那些需要处理大量非结构化或半结构化数据的应用程序。MongoDB 是一个文档数据库,为简化应用程序的开发与扩展而设计。MongoDB 中的记录是一个文档,它是由字段和值对组成的数据结构。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档、数组和文档数组。MongoDB 将文档存储在集合中。集合类似于关系数据库中的表。


在这里插入图片描述

图中展示的是MongoDB容器中的三个内置数据库及其对应的系统集合。让我们逐一介绍它们:

  1. local 数据库:local数据库主要用于存储特定于单个MongoDB实例的数据。 startup_log是一个日志集合,记录了MongoDB服务器启动时的一些重要事件。

  2. config 数据库:config数据库仅在分片集群中使用,用于存储分片集群的配置信息。system.sessions存储跨多个分片的操作会话信息(自MongoDB 4.0开始引入)。

  3. admin 数据库:admin数据库是一个特殊的“超级用户”数据库,用于执行管理任务,如运行权限检查、数据库查询等。它包含一个名为system.users的集合,其中存储着全局用户的认证信息。system.version存储MongoDB版本信息(自MongoDB 4.2开始引入)。


🌕文档(Document)

☘️官方详细概念:https://www.mongodb.com/zh-cn/docs/manual/core/document/

MongoDB 将数据记录存储为 BSON 文档。BSONJSON 文档的二进制表示形式,但它包含的数据类型比 JSON 多。

在这里插入图片描述

🌖文档结构

MongoDB 文档由字段对组成,具有以下结构:

{
   field1: value1,
   field2: value2,
   field3: value3,
   ...
   fieldN: valueN
}

字段值可以是任何一种 BSON 数据类型,包括其他文档、数组和文档数组。例如,以下文档包含不同类型的值:

var mydoc = {
               _id: ObjectId("5099803df3f4948bd2f98391"),
               name: { first: "Alan", last: "Turing" },
               birth: new Date('Jun 23, 1912'),
               death: new Date('Jun 07, 1954'),
               contribs: [ "Turing machine", "Turing test", "Turingery" ],
               views : NumberLong(1250000)
            }

🌖QUERY / Find DOCUMENT

☘️详细语法:db.collection.find(query, projection, options)

db.collection.findOne(query, projection, options)

读取操作用于从集合检索文档,即查询集合中的文档。

🌰:选择集合中的所有文档

-- 查询所有文档
db.inventory.find( {} )

-- 该操作使用 {} 的过滤谓词,对应以下 SQL 声明:
SELECT * FROM inventory

🌰:指定相等条件

-- 从 inventory 中选择集合所有 status 等于 "D" 的文档:
db.inventory.find( { status: "D" } )

-- 该操作使用 { status: "D" } 的过滤谓词,对应以下 SQL 声明:
SELECT * FROM inventory WHERE status = "D"

🌰:使用查询操作符指定条件

-- 从 inventory 集合中检索所有文档。其中 status 等于 "A" 或 "D":
db.inventory.find( { status: { $in: [ "A", "D" ] } } )

-- 该操作使用 { status: { $in: [ "A", "D" ] } } 的过滤谓词,对应以下 SQL 声明:
SELECT * FROM inventory WHERE status in ("A", "D")

🌰:指定 AND 条件。复合查询可以为集合文档中的多个字段指定条件。逻辑 AND 连接词隐式地连接复合查询的子句,以便该查询选择集合中与所有条件匹配的文档。

-- 检索 inventory 集合中 status 等于 "A" 且qty 小于 ($lt) 30 的所有文档:
db.inventory.find( { status: "A", qty: { $lt: 30 } } )

-- 该操作使用 { status: "A", qty: { $lt: 30 } } 的过滤谓词,对应以下 SQL 声明:
SELECT * FROM inventory WHERE status = "A" AND qty < 30

🌰:指定 OR 条件。可以使用 $or 操作符指定复合查询,该复合查询使用逻辑 OR 连接词连接每个每个子句,以便该查询选择集合中至少匹配一个条件的文档。

-- 检索集合中 status 等于 "A" 或 qty 小于 ($lt) 30 的所有文档:
db.inventory.find( { $or: [ { status: "A" }, { qty: { $lt: 30 } } ] } )

-- 该操作使用 { $or: [ { status: 'A' }, { qty: { $lt: 30 } } ] } 的过滤谓词,对应以下 SQL 声明:
SELECT * FROM inventory WHERE status = "A" OR qty < 30

🌰:指定 ANDOR 条件

-- 复合查询文档选择集合中 status 等于 "A" 小于 ( 且 ) 以字符 30 开头的文档:$ltitem 或 p
db.inventory.find( {
     status: "A",
     $or: [ { qty: { $lt: 30 } }, { item: /^p/ } ]
} )

-- 对应如下 SQL 语句:
SELECT * FROM inventory WHERE status = "A" AND ( qty < 30 OR item LIKE "p%")

🌰:使用空查询规范。虽然与 find() 方法类似,但 findOne() 方法返回的是文档而不是游标。

db.bios.findOne()

🌰:返回 BIOS 集合中的第一个匹配文档,其中嵌入式文档 name 中的字段 first 以字母 G 开头,或者字段 birth 小于 new Date(‘01/01/1945’):

db.bios.findOne(
   {
     $or: [
            { 'name.first' : /^G/ },
            { birth: { $lt: new Date('01/01/1945') } }
          ]
   }
)

🌰:返回 BIOS 集合中的文档(contribs 字段包含元素 OOP),并返回除 之外的 字段、_id 嵌入式文档中的 name 字段和 first birth所有字段:

db.bios.findOne(
   { contribs: 'OOP' },
   { _id: 0, 'name.first': 0, birth: 0 }
)

🌗CREATE / Insert DOCUMENT

☘️详细语法:https://www.mongodb.com/zh-cn/docs/manual/tutorial/insert-documents/

创建插入操作用于将新文档添加到集合中。 如果集合当前不存在,插入操作会创建集合。在 MongoDB 中,存储在集合中的每个文档都需要一个唯一的 _id 字段作为主键。如果插入的文档省略了 _id 字段,MongoDB 驱动程序会自动为 ObjectId 字段生成一个 _id

🌰:Collection.insertOne()将单个文档插入到集合中。

-- 将新文档插入 `inventory` 集合。
db.inventory.insertOne(
   { item: "canvas", qty: 100, tags: ["cotton"], size: { h: 28, w: 35.5, uom: "cm" } }
)

-- 要检索刚刚插入的文档,请查询该集合:
db.inventory.find( { item: "canvas" } )

在这里插入图片描述

🌰:db.collection.insertMany() 可以将多个文档插入到一个集合中。

-- 将三个新文档插入inventory集合。
db.inventory.insertMany([
   { item: "journal", qty: 25, tags: ["blank", "red"], size: { h: 14, w: 21, uom: "cm" } },
   { item: "mat", qty: 85, tags: ["gray"], size: { h: 27.9, w: 35.5, uom: "cm" } },
   { item: "mousepad", qty: 25, tags: ["gel", "blue"], size: { h: 19, w: 22.85, uom: "cm" } }
])

-- 要检索插入的文档,请查询集合
db.inventory.find( {} )

在这里插入图片描述

🌰(高深):bios 集合提供了用于 MongoDB 实验的示例数据。
https://www.mongodb.com/zh-cn/docs/manual/reference/bios-example-collection/#std-label-bios-example-collection

db.bios.insertMany([
   {
       "_id" : 1,
       "name" : {
           "first" : "John",
           "last" : "Backus"
       },
       "birth" : ISODate("1924-12-03T05:00:00Z"),
       "death" : ISODate("2007-03-17T04:00:00Z"),
       "contribs" : [
           "Fortran",
           "ALGOL",
           "Backus-Naur Form",
           "FP"
       ],
       
       ......
       
   {
       "_id" : 10,
       "name" : {
           "first" : "Martin",
           "last" : "Odersky"
       },
       "contribs" : [
           "Scala"
       ]
   }

] )

在这里插入图片描述

🌘UPDATE DOCUMENT

☘️详细语法:https://www.mongodb.com/zh-cn/docs/manual/tutorial/update-documents/

更新操作用于修改集合中的现有文档 。

🌰:使用 db.collection.updateOne() 集合上的 inventory 方法来更新 第一个 等于 item 的"paper"文档:

db.inventory.updateOne(
   { item: "paper" },
   {
     $set: { "size.uom": "cm", status: "P" },
     $currentDate: { lastModified: true }
   }
)

🌰:使用 db.collection.updateMany() 集合上的 inventory 方法更新 qty 小于 50 的所有文档:

db.inventory.updateMany(
   { "qty": { $lt: 50 } },
   {
     $set: { "size.uom": "in", status: "P" },
     $currentDate: { lastModified: true }
   }
)

🌰:替换除 _id 字段之外的文档的所有内容,请将全新文档作为第二个参数传递给 db.collection.replaceOne()

db.inventory.replaceOne(
   { item: "paper" },
   { item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 40 } ] }
)

🌑DELETE DOCUMENT

☘️详细语法:https://www.mongodb.com/zh-cn/docs/manual/tutorial/remove-documents/

删除操作用于从集合中删除文档。

🌰:要删除集合中的所有文档,请将空的过滤器文档 {} 传递给 db.collection.deleteMany() 方法。

-- 删除 所有 集合中的inventory文档:
db.inventory.deleteMany({})

🌰:指定条件或过滤器来标识要删除的文档。

-- 从 status 字段等于 "A" 的 inventory 集合中删除所有文档:
db.inventory.deleteMany({ status : "A" })

🌰:要删除最多一个与指定的筛选器匹配的文档(即使指定的筛选器可能存在多个匹配的文档),请使用 db.collection.deleteOne() 方法。

-- 删除 第一个 为 `status 的"D"`文档:
db.inventory.deleteOne( { status: "D" } )

更多方法:https://www.mongodb.com/zh-cn/docs/manual/reference/method/

在这里插入图片描述

Redis

在这里插入图片描述
官网介绍:https://redis.io/docs/latest/?spm=5176.28103460.0.0.297c572cWOYo4Z

Redis (Remote Dictionary Server) 是一个开源的、高性能的、基于内存的数据结构存储系统。它不仅仅是一个简单的键值存储系统,还支持多种数据结构,如字符串(String)哈希(Hash)列表(List)集合(Set)有序集合(Zset)等。这些数据结构使得 Redis 成为一个非常灵活的工具,可以用于多种场景,如缓存、消息队列、实时分析等。

🌕字符串(String)

🌖SET key value

☘️详细语法:https://redis.io/docs/latest/commands/set/

设置键 key 的值为 value

🌰:

-- 创建一个键 mykey,并将其值设置为 "Hello"。
-- 如果 mykey 已经存在,那么这个命令会更新 mykey 的值为 "Hello"。
SET mykey "Hello"

-- 在 Redis 中创建一个键 anotherkey,并将其值设为 "will expire in a minute"
-- 同时设置这个键的过期时间为 60 秒。60 秒后,这个键将自动从 Redis 中删除。
SET anotherkey "will expire in a minute" EX 60

在这里插入图片描述

🌗GET key

☘️详细语法:https://redis.io/docs/latest/commands/get/

获取键 key 的值。

🌰:

-- 如果 mykey 存在,Redis 会返回其对应的值。
-- 如果 mykey 不存在,Redis 会返回 nil(空值)。
GET mykey

🌘INCR key

☘️详细语法:https://redis.io/docs/latest/commands/incr/

将键 key 的值增 1,如果键不存在,则先初始化为 0 再增 1。

🌰:

redis> SET mykey "10"
"OK"
redis> INCR mykey
(integer) 11
redis> GET mykey
"11"

🌑DECR key

☘️详细语法:https://redis.io/docs/latest/commands/decr/

将键 key 的值减 1,如果键不存在,则先初始化为 0 再减 1。

🌰:

redis> SET mykey "10"
"OK"
redis> DECR mykey
(integer) 9
redis> SET mykey "234293482390480948029348230948"
"OK"
redis> DECR mykey
(error) value is not an integer or out of range

🌕哈希(Hash)

🌖HSET key field value

☘️详细语法:https://redis.io/docs/latest/commands/hset/

将哈希表 key 中的字段 field 的值设为 value

🌰:

redis> HSET myhash field1 "Hello"
"OK"
redis> HGET myhash field1
"Hello"
redis> HSET myhash field2 "Hi" field3 "World"
"OK"
redis> HGET myhash field2
"Hi"
redis> HGET myhash field3
"World"
redis> HGETALL myhash
(如下图)

在这里插入图片描述

🌗HGET key field

☘️详细语法:https://redis.io/docs/latest/commands/hget/

获取哈希表 key 中字段 field 的值。

🌰:

redis> HSET myhash field1 "foo"
(integer) 1
redis> HGET myhash field1
"foo"
redis> HGET myhash field2
(nil)

🌘HGETALL key

☘️详细语法:https://redis.io/docs/latest/commands/hgetall/

获取哈希表 key 中所有字段和值。

🌰:

redis> HSET myhash field1 "Hello"
(integer) 0
redis> HSET myhash field2 "World"
(integer) 0
redis> HGETALL myhash
1) "field1"
2) "Hello"
3) "field2"
4) "World"

在这里插入图片描述

🌕列表(List)

🌖LPUSH key value

☘️详细语法:https://redis.io/docs/latest/commands/lpush/

将一个或多个值 value 插入到列表 key 的表头。

🌰:

redis> LPUSH mylist "world"
(integer) 1
redis> LPUSH mylist "hello"
(integer) 2
redis> LRANGE mylist 0 -1
1) "hello"
2) "world"

在这里插入图片描述

🌗RPUSH key value

☘️详细语法:https://redis.io/docs/latest/commands/rpush/

将一个或多个值 value 插入到列表 key 的表尾。

🌰:

redis> RPUSH mylist "hello"
(integer) 3
redis> RPUSH mylist "world"
(integer) 4
redis> LRANGE mylist 0 -1
(如下图,先前已经LPUSH了,所以4个数据)

在这里插入图片描述

🌘LPOP key

☘️详细语法:https://redis.io/docs/latest/commands/lpop/

移除并获取列表 key 的第一个元素。

🌰:

redis> RPUSH mylist "one" "two" "three" "four" "five"
(integer) 9
redis> LPOP mylist
"hello"
redis> LPOP mylist 2
1)world
2)hello
redis> LRANGE mylist 0 -1
(如下图)

在这里插入图片描述

🌑RPOP key

☘️详细语法:https://redis.io/docs/latest/commands/rpop/

移除并获取列表 key 的最后一个元素。

🌰:

redis> RPUSH mylist "one" "two" "three" "four" "five"
(integer) 5
redis> RPOP mylist
"five"
redis> RPOP mylist 2
1) "four"
2) "three"
redis> LRANGE mylist 0 -1
1) "one"
2) "two"

在这里插入图片描述

🌑LRANGE key start stop

☘️详细语法:https://redis.io/docs/latest/commands/lrange/

获取列表 key 中指定范围的元素。

🌰:

redis> RPUSH mylist "one"
(integer) 1
redis> RPUSH mylist "two"
(integer) 2
redis> RPUSH mylist "three"
(integer) 3
redis> LRANGE mylist 0 0
1) "one"
redis> LRANGE mylist -3 2
1) "one"
2) "two"
3) "three"
redis> LRANGE mylist -100 100
1) "one"
2) "two"
3) "three"
redis> LRANGE mylist 5 10
(empty array)

🌕集合(Set)

🌖SADD key member

☘️详细语法:https://redis.io/docs/latest/commands/sadd/

将一个成员 member 添加到集合 key 中。

🌰:

redis> SADD myset "Hello"
(integer) 1
redis> SADD myset "World"
(integer) 1
redis> SADD myset "World"
(integer) 0
redis> SMEMBERS myset
1) "Hello"
2) "World"

🌗SMEMBERS key

☘️详细语法:https://redis.io/docs/latest/commands/smembers/

获取集合 key 中的所有成员。

🌰:

redis> SADD myset "Hello"
(integer) 1
redis> SADD myset "World"
(integer) 1
redis> SMEMBERS myset
1) "Hello"
2) "World"

🌘SREM key member

☘️详细语法:https://redis.io/docs/latest/commands/srem/

从集合 key 中移除一个成员 member

🌰:

redis> SADD myset "one"
(integer) 1
redis> SADD myset "two"
(integer) 1
redis> SADD myset "three"
(integer) 1
redis> SREM myset "one"
(integer) 1
redis> SREM myset "four"
(integer) 0
redis> SMEMBERS myset
1) "two"
2) "three"

在这里插入图片描述

🌑SCARD key

☘️详细语法:https://redis.io/docs/latest/commands/scard/

获取集合 key 的基数(即成员数量)。

🌰:

redis> SADD myset "Hello"
(integer) 1
redis> SADD myset "World"
(integer) 1
redis> SCARD myset
(integer) 2

🌕有序集合(Zset)

🌖ZADD key score member

☘️详细语法:https://redis.io/docs/latest/commands/zadd/

将一个成员 member 添加到有序集合 key 中,并为其设置一个分数 score

🌰:

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 1 "uno"
(integer) 1
redis> ZADD myzset 2 "two" 3 "three"
(integer) 2
redis> ZRANGE myzset 0 -1 WITHSCORES
1) "one"
2) "1"
3) "uno"
4) "1"
5) "two"
6) "2"
7) "three"
8) "3"

在这里插入图片描述

🌗ZRANGE key start stop [WITHSCORES]

☘️详细语法:https://redis.io/docs/latest/commands/zrange/

获取有序集合 key 中指定范围的成员,可选参数 [WITHSCORES] 表示同时获取分数。

🌰:

redis> ZADD myzset 1 "one" 2 "two" 3 "three"
(integer) 3
redis> ZRANGE myzset 0 -1
1) "one"
2) "two"
3) "three"
redis> ZRANGE myzset 2 3
1) "three"
redis> ZRANGE myzset -2 -1
1) "two"
2) "three"

🌰:此示例显示如何按分数查询排序集,不包括值1并直到无穷大,仅返回结果的第二个元素。

redis> ZADD myzset 1 "one" 2 "two" 3 "three"
(integer) 3
redis> ZRANGE myzset (1 +inf BYSCORE LIMIT 1 1
1) "three"

🌘ZREM key member

☘️详细语法:https://redis.io/docs/latest/commands/zrem/

从有序集合 key 中移除一个成员 member

🌰:

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZADD myzset 3 "three"
(integer) 1
redis> ZREM myzset "two"
(integer) 1
redis> ZRANGE myzset 0 -1 WITHSCORES
1) "one"
2) "1"
3) "three"
4) "3"

🌑ZCARD key

☘️详细语法:https://redis.io/docs/latest/commands/zcard/

获取有序集合 key 的基数(即成员数量)。

🌰:

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZCARD myzset
(integer) 2

🌕其他

🌖DEL key

☘️详细语法: https://redis.io/docs/latest/commands/del/

删除一个或多个键。

🌰:

redis> SET key1 "Hello"
"OK"
redis> SET key2 "World"
"OK"
redis> DEL key1 key2 key3
(integer) 2

🌗EXISTS key

☘️详细语法:https://redis.io/docs/latest/commands/exists/

检查给定的键是否存在。

🌰:

redis> SET key1 "Hello"
"OK"
redis> EXISTS key1
(integer) 1
redis> EXISTS nosuchkey
(integer) 0
redis> SET key2 "World"
"OK"
redis> EXISTS key1 key2 nosuchkey
(integer) 2

🌘KEYS pattern

☘️详细语法:https://redis.io/docs/latest/commands/keys/

查找所有匹配给定模式的键。

🌰:

-- MSET同时设置一个或多个键值对。
redis> MSET firstname Jack lastname Stuntman age 35
"OK"
redis> KEYS *name*
1) "lastname"
2) "firstname"
redis> KEYS a??
1) "age"
redis> KEYS *
1) "lastname"
2) "firstname"
3) "age"

🌑EXPIRE key seconds

☘️详细语法:https://redis.io/docs/latest/commands/expire/

设置键 key 的生存时间(以秒为单位)。

🌰:

redis> SET mykey "Hello"
"OK"
redis> EXPIRE mykey 10
(integer) 1
redis> TTL mykey
(integer) 10
redis> SET mykey "Hello World"
"OK"
redis> TTL mykey
(integer) -1
-- XX — 仅当密钥已有到期时间时才设置到期时间
-- GT — 仅当新到期时间大于当前到期时间时才设置到期时间
-- LT — 仅当新到期时间小于当前到期时间时才设置到期时间
redis> EXPIRE mykey 10 XX
(integer) 0
redis> TTL mykey
(integer) -1
-- NX — 仅当密钥没有到期时才设置到期时间
redis> EXPIRE mykey 10 NX
(integer) 1
redis> TTL mykey
(integer) 10

当然了除了这些命令,还有很多常用的命令:SAVEBGSAVELASTSAVETTL key等等。

更多命令:https://redis.io/docs/latest/commands/


综括而言

👋通过本文的学习,我们不仅了解了 MongoDBRedis 的基本概念,还掌握了它们的核心功能和操作方法。MongoDB 作为一种面向文档的数据库,提供了灵活的数据模型和强大的查询语言,适用于存储复杂的数据结构。Redis 则以其超高的性能和丰富的数据结构,成为了构建高性能应用和服务的理想选择。

🌈无论是需要处理大量文档数据还是寻求高速缓存解决方案MongoDBRedis 都能提供有效的支持。希望读者能够通过本篇文章获得足够的知识基础,进一步探索这两种数据库的高级特性,并将其应用到实际工作中,提升应用的性能和稳定性。未来,随着对这些技术的深入理解,你将能够更好地利用它们的优势来解决实际问题。

  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值