dot Redis 8 来了—而且是开源的

了解更多

Redis OM for Node.js 简介

适用于 JavaScript 和 TypeScript 的快速简便的对象映射

我写了一个东西——好吧,实际上我们几个人写了东西——我只是写了 Node.js 版本。我认为这是一个非常酷的东西,值得您关注,我对此感到兴奋。 我要谈论的东西:Redis OM for Node.js

什么是 Redis OM? Redis OM 是一个库,通过将 Redis 数据结构直接映射到您的代码,可以轻松使用 Redis。 OM 代表对象映射,但我们计划将来做更多的事情。

请继续阅读以了解更多详情。

比快更快

您可能已经知道 Redis 速度很快 - 比快更快 - 它存储您的程序关心的各种东西:哈希、列表、集合等等。这些是我作为程序员所思考的结构。 当我向一个没有经验的技术人员解释 Redis 是什么时,我会告诉他们 Redis 是你在大学里学到的所有数据结构,并在它们前面放了一个线路协议。

特性通过引入您的程序关心的新的数据结构,使 Redis 更加出色(是的,我知道这不是一个词)。概率的添加了概率数据结构,如 Bloom 和 Cuckoo 过滤器。

最出色的模块

但是有两个模块特别使得 Redis 成为每个程序员都想要的强大的内存数据库:JSON搜索和查询

JSON 将层次结构带到了表中。 哈希很棒,但是如果你想在哈希中嵌入哈希怎么办? JSON 通过允许你将我的分层数据存储在 JSON 文档中来满足你的需求。

与此同时,搜索和查询让你查找你关心的数据结构。 当然,你可以使用集合创建手动索引,但这种方法是有限的和手动的。 呸。 搜索和查询让你编写查询来直接查找你想要的数据。

结合起来,搜索和查询以及 JSON 使 Redis 成为一个非常好的文档数据库。 你获得了你想要的层次结构,并且能够找到你关心的东西。 两全其美。

事实上,我们认为这是一个如此美味的组合,我们正在将它们组合在一起,并称它们为 JSON。

Redis OM for Node.js

搜索和查询的查询语言非常强大。 非常强大。 它允许你以各种复杂的方式搜索 Redis 中的哈希和 JSON 文档。 当我需要所有这些力量时,它非常酷。 但有时我不需要所有这些力量。 而且我一个懒惰的开发者——我希望它尽可能简单(并且没有更容易的)。

当我编写 Redis OM for Node.js 时,我试图尽可能地简化事情。 Redis OM 通过将哈希和 JSON 文档映射到你定义的类,从而使将 Redis 添加到你的 Node.js 应用程序变得简单。 没有复杂的命令,只有具有流畅接口的纯代码。 看看。

定义一个实体

class Album extends Entity {}

let schema = new Schema(Album, {
  artist: { type: 'string' },
  title: { type: 'string', textSearch: true },
  year: { type: 'number' }
});

创建一个新实体并保存它

let album = repository.createEntity()
album.artist = "Mushroomhead"
album.title = "The Righteous & The Butterfly"
album.year = 2014
await repository.save(album)

搜索匹配的实体

let albums = await repository.search()
  .where('artist').equals('Mushroomhead')
  .and('title').matches('butterfly')
  .and('year').is.greaterThan(2000).returnAll()

既然我写了这个库,我有点偏见,但我认为这非常酷! 让我们仔细看看这个语法,了解它是如何工作的。

它是如何工作的

在 Redis OM for Node.js 中,你需要关心四个类。 它们是 Entity、Schema、Client 和 Repository。

import { Entity, Schema, Client, Repository } from 'redis-om'
class Album extends Entity {}
let schema = new Schema(Album, {
  artist: { type: 'string' },
  title: { type: 'string' },
  year: { type: 'number' },
  genres: { type: 'array' },
  outOfPublication: { type: 'boolean' }
})
let client = new Client()
await client.open('redis://localhost:6379')
let repository = new Repository(schema, client)
let album, id

// create an entity and save it
album = repository.createEntity()

album.artist = "Mushroomhead"
album.title = "The Righteous & The Butterfly"
album.year = 2014
album.genres = [ 'metal' ]
album.outOfPublication = true

id = await repository.save(album) // '01FJYWEYRHYFT8YTEGQBABJ43J'

// read an entity
album = await repository.fetch('01FJYWEYRHYFT8YTEGQBABJ43J')

// update an entity
album.genres = [ 'metal', 'nu metal', 'avantgarde' ]
album.outOfPublication = false

id = await repository.save(album) // '01FJYWEYRHYFT8YTEGQBABJ43J'

// delete an entity
await repository.remove('01FJYWEYRHYFT8YTEGQBABJ43J')
let albums = await repository.search()
  .where('artist').equals('Mushroomhead')
  .and('title').matches('butterfly')
  .and('year').is.greaterThan(2000).returnAll()

实体是你使用的类。 正在创建、读取、更新和删除的东西。 正在搜索的东西。 任何扩展 Entity 的类都是一个实体。 通常,你将使用一行代码定义一个实体,但你也可以在其中添加自定义逻辑

import { Entity, Schema, Client, Repository } from 'redis-om'
class Album extends Entity {}
let schema = new Schema(Album, {
  artist: { type: 'string' },
  title: { type: 'string' },
  year: { type: 'number' },
  genres: { type: 'array' },
  outOfPublication: { type: 'boolean' }
})
let client = new Client()
await client.open('redis://localhost:6379')
let repository = new Repository(schema, client)
let album, id

// create an entity and save it
album = repository.createEntity()

album.artist = "Mushroomhead"
album.title = "The Righteous & The Butterfly"
album.year = 2014
album.genres = [ 'metal' ]
album.outOfPublication = true

id = await repository.save(album) // '01FJYWEYRHYFT8YTEGQBABJ43J'

// read an entity
album = await repository.fetch('01FJYWEYRHYFT8YTEGQBABJ43J')

// update an entity
album.genres = [ 'metal', 'nu metal', 'avantgarde' ]
album.outOfPublication = false

id = await repository.save(album) // '01FJYWEYRHYFT8YTEGQBABJ43J'

// delete an entity
await repository.remove('01FJYWEYRHYFT8YTEGQBABJ43J')
let albums = await repository.search()
  .where('artist').equals('Mushroomhead')
  .and('title').matches('butterfly')
  .and('year').is.greaterThan(2000).returnAll()

Schema定义了你的实体上的字段、它们的类型以及它们如何在内部映射到 Redis。 默认情况下,实体映射到 Redis 中的哈希,但你也可以将它们映射到 JSON 文档

import { Entity, Schema, Client, Repository } from 'redis-om'
class Album extends Entity {}
let schema = new Schema(Album, {
  artist: { type: 'string' },
  title: { type: 'string' },
  year: { type: 'number' },
  genres: { type: 'array' },
  outOfPublication: { type: 'boolean' }
})
let client = new Client()
await client.open('redis://localhost:6379')
let repository = new Repository(schema, client)
let album, id

// create an entity and save it
album = repository.createEntity()

album.artist = "Mushroomhead"
album.title = "The Righteous & The Butterfly"
album.year = 2014
album.genres = [ 'metal' ]
album.outOfPublication = true

id = await repository.save(album) // '01FJYWEYRHYFT8YTEGQBABJ43J'

// read an entity
album = await repository.fetch('01FJYWEYRHYFT8YTEGQBABJ43J')

// update an entity
album.genres = [ 'metal', 'nu metal', 'avantgarde' ]
album.outOfPublication = false

id = await repository.save(album) // '01FJYWEYRHYFT8YTEGQBABJ43J'

// delete an entity
await repository.remove('01FJYWEYRHYFT8YTEGQBABJ43J')
let albums = await repository.search()
  .where('artist').equals('Mushroomhead')
  .and('title').matches('butterfly')
  .and('year').is.greaterThan(2000).returnAll()

当你创建一个 Schema 时,它会修改你传递给它的 Entity,为定义的属性添加 getter 和 setter。 这些 getter 和 setter 接受和返回的类型由上面的 type 属性定义。

客户端将你连接到 Redis。 客户端具有打开、关闭和针对 Redis 执行原始命令的方法。 你主要使用 open 和 close

import { Entity, Schema, Client, Repository } from 'redis-om'
class Album extends Entity {}
let schema = new Schema(Album, {
  artist: { type: 'string' },
  title: { type: 'string' },
  year: { type: 'number' },
  genres: { type: 'array' },
  outOfPublication: { type: 'boolean' }
})
let client = new Client()
await client.open('redis://localhost:6379')
let repository = new Repository(schema, client)
let album, id

// create an entity and save it
album = repository.createEntity()

album.artist = "Mushroomhead"
album.title = "The Righteous & The Butterfly"
album.year = 2014
album.genres = [ 'metal' ]
album.outOfPublication = true

id = await repository.save(album) // '01FJYWEYRHYFT8YTEGQBABJ43J'

// read an entity
album = await repository.fetch('01FJYWEYRHYFT8YTEGQBABJ43J')

// update an entity
album.genres = [ 'metal', 'nu metal', 'avantgarde' ]
album.outOfPublication = false

id = await repository.save(album) // '01FJYWEYRHYFT8YTEGQBABJ43J'

// delete an entity
await repository.remove('01FJYWEYRHYFT8YTEGQBABJ43J')
let albums = await repository.search()
  .where('artist').equals('Mushroomhead')
  .and('title').matches('butterfly')
  .and('year').is.greaterThan(2000).returnAll()

实例化 Repository 需要 Schema 和 Client。 Repositories提供读取、写入和删除实体的方法。 以及搜索它们的方法

import { Entity, Schema, Client, Repository } from 'redis-om'
class Album extends Entity {}
let schema = new Schema(Album, {
  artist: { type: 'string' },
  title: { type: 'string' },
  year: { type: 'number' },
  genres: { type: 'array' },
  outOfPublication: { type: 'boolean' }
})
let client = new Client()
await client.open('redis://localhost:6379')
let repository = new Repository(schema, client)
let album, id

// create an entity and save it
album = repository.createEntity()

album.artist = "Mushroomhead"
album.title = "The Righteous & The Butterfly"
album.year = 2014
album.genres = [ 'metal' ]
album.outOfPublication = true

id = await repository.save(album) // '01FJYWEYRHYFT8YTEGQBABJ43J'

// read an entity
album = await repository.fetch('01FJYWEYRHYFT8YTEGQBABJ43J')

// update an entity
album.genres = [ 'metal', 'nu metal', 'avantgarde' ]
album.outOfPublication = false

id = await repository.save(album) // '01FJYWEYRHYFT8YTEGQBABJ43J'

// delete an entity
await repository.remove('01FJYWEYRHYFT8YTEGQBABJ43J')
let albums = await repository.search()
  .where('artist').equals('Mushroomhead')
  .and('title').matches('butterfly')
  .and('year').is.greaterThan(2000).returnAll()

一旦我们有了 repository,我们就可以使用它来创建、读取、更新和删除实体。 在这里,我正在用我最喜欢的 Mushroomhead 专辑来做这件事

import { Entity, Schema, Client, Repository } from 'redis-om'
class Album extends Entity {}
let schema = new Schema(Album, {
  artist: { type: 'string' },
  title: { type: 'string' },
  year: { type: 'number' },
  genres: { type: 'array' },
  outOfPublication: { type: 'boolean' }
})
let client = new Client()
await client.open('redis://localhost:6379')
let repository = new Repository(schema, client)
let album, id

// create an entity and save it
album = repository.createEntity()

album.artist = "Mushroomhead"
album.title = "The Righteous & The Butterfly"
album.year = 2014
album.genres = [ 'metal' ]
album.outOfPublication = true

id = await repository.save(album) // '01FJYWEYRHYFT8YTEGQBABJ43J'

// read an entity
album = await repository.fetch('01FJYWEYRHYFT8YTEGQBABJ43J')

// update an entity
album.genres = [ 'metal', 'nu metal', 'avantgarde' ]
album.outOfPublication = false

id = await repository.save(album) // '01FJYWEYRHYFT8YTEGQBABJ43J'

// delete an entity
await repository.remove('01FJYWEYRHYFT8YTEGQBABJ43J')
let albums = await repository.search()
  .where('artist').equals('Mushroomhead')
  .and('title').matches('butterfly')
  .and('year').is.greaterThan(2000).returnAll()

我们也可以使用它来搜索实体

import { Entity, Schema, Client, Repository } from 'redis-om'
class Album extends Entity {}
let schema = new Schema(Album, {
  artist: { type: 'string' },
  title: { type: 'string' },
  year: { type: 'number' },
  genres: { type: 'array' },
  outOfPublication: { type: 'boolean' }
})
let client = new Client()
await client.open('redis://localhost:6379')
let repository = new Repository(schema, client)
let album, id

// create an entity and save it
album = repository.createEntity()

album.artist = "Mushroomhead"
album.title = "The Righteous & The Butterfly"
album.year = 2014
album.genres = [ 'metal' ]
album.outOfPublication = true

id = await repository.save(album) // '01FJYWEYRHYFT8YTEGQBABJ43J'

// read an entity
album = await repository.fetch('01FJYWEYRHYFT8YTEGQBABJ43J')

// update an entity
album.genres = [ 'metal', 'nu metal', 'avantgarde' ]
album.outOfPublication = false

id = await repository.save(album) // '01FJYWEYRHYFT8YTEGQBABJ43J'

// delete an entity
await repository.remove('01FJYWEYRHYFT8YTEGQBABJ43J')
let albums = await repository.search()
  .where('artist').equals('Mushroomhead')
  .and('title').matches('butterfly')
  .and('year').is.greaterThan(2000).returnAll()

并且,为了你复制和粘贴的方便,这里是将该样本作为一个大的代码块

import { Entity, Schema, Client, Repository } from 'redis-om'

class Album extends Entity {}
let schema = new Schema(Album, {
  artist: { type: 'string' },
  title: { type: 'string' },
  year: { type: 'number' },
  genres: { type: 'array' },
  outOfPublication: { type: 'boolean' }
})

let client = new Client()
await client.open('redis://localhost:6379')

let repository = new Repository(schema, client)

let album, id

// create an entity and save it
album = repository.createEntity()

album.artist = "Mushroomhead"
album.title = "The Righteous & The Butterfly"
album.year = 2014
album.genres = [ 'metal' ]
album.outOfPublication = true

id = await repository.save(album) // '01FJYWEYRHYFT8YTEGQBABJ43J'

// read an entity
album = await repository.fetch('01FJYWEYRHYFT8YTEGQBABJ43J')

// update an entity
album.genres = [ 'metal', 'nu metal', 'avantgarde' ]
album.outOfPublication = false

id = await repository.save(album) // '01FJYWEYRHYFT8YTEGQBABJ43J'

// delete an entity
await repository.remove('01FJYWEYRHYFT8YTEGQBABJ43J')

let albums = await repository.search()
  .where('artist').equals('Mushroomhead')
  .and('title').matches('butterfly')
  .and('year').is.greaterThan(2000).returnAll()

这就是 Redis OM for Node.js,正如他们所说,简而言之。

总结

这已经是对 Redis OM for Node.js 可以做什么的快速概述。 如果你想了解更多,这里有一个教程,它将指导你使用 Redis OM 构建一个简单的服务。 如果你想深入了解,你应该这样做,请查看 GitHub 上的 READMEAPI 文档

当然,这是一个全新的软件,尚未在野外进行测试。 就是那个野外。 请尝试一下。 踢踢轮胎。 试着破坏它。 看看那里有什么,可能有什么。 当你发现那个 bug 或想到那个完美的功能时,请通过打开一个 issue发送一个 pull request 来告诉我。 非常感谢你帮助改进 Redis OM。 谢谢!