dot 快速发展的未来正向你所在的城市迈进。

加入我们的 Redis 发布会

Redis OM 对于 Node.JS 有何最新进展?

Redis OM for Node.js 仍处于早期阶段,但我们取得了很多进展。以下是我们最新版本中添加的内容以及我们的发展方向。

几个月前,我发布了 Node.js 的 Redis OM 预览版。那时我对此感到非常满意。它执行了它应该执行的操作,至少在这个开发周期的早期是如此。 

让我特别满意的一项因素是搜索的流畅界面。你知道,这款产品

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

但最棒的部分(也是让我最满意的部分)是,Node.js 的 Redis OM 备受开发者社区的青睐和使用。你们中的许多人通过我们的 Discord 服务器 向我提供了许多有用的可操作反馈。此外,你们修复了错误,甚至从我在 GitHub 上定义相当稀疏的问题中发送了完整功能。我真心感谢你们的帮助。

我已经合并了你们的反馈和你们的发起请求,以及你们的贡献。在这篇文章中,我总结了一些我们(我所说的“我们”指的是“你和我是”)对 Redis OM 所做的更改。

更轻松的实体创建

早期,Internet 上的某个陌生人建议,对 .createEntity 的调用应该采用该实体的初始值。我认为这是一个绝妙的主意,并在 Redis OM 中采用了它。

因此,曾经有点冗长的东西

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

const id = await albumRepository.save(album)

变得更加简洁

const album = albumRepository.createEntity({
  artist: "Mushroomhead",
  title: "The Righteous & The Butterfly",
  year: 2014,
  genres: [ 'metal' ],
  outOfPublication: true
})

const id = await albumRepository.save(album)

我甚至添加了一个 .createAndSave 方法来消除对 .save 的调用,因为这是一个非常常见的模式

const album = await albumRepository.createAndSave({
  artist: "Mushroomhead",
  title: "The Righteous & The Butterfly",
  year: 2014,
  genres: [ 'metal' ],
  outOfPublication: true
})

感谢你的建议。这建议很有价值。

到期实体

Redis 是一个很棒的数据库,但同时也是一个非常好的缓存。你们中的许多人建议,我们需要一种创建到期实体的方法。 

希望如此,收获亦然

const ttlInSeconds = 12 * 60 * 60  // 12 hours
await albumRepository.expire('01FVDN241NGTPHSAV0DFDBXC90', ttlInSeconds)

不确定你为什么想要让 Mushroomhead 专辑到期,但 de gustibus non est disputandum。

指向和日期类型

没有人要求这些,但我仍然想要它们!RediSearch 对 GEO 类型的位置提供了良好的支持,并且各种应用程序中都使用日期。所以我将其分别添加为 指向和日期。

const studioSchema = new Studio(Studio, {
  name: { type: 'string' },
  city: { type: 'string' },
  state: { type: 'string' },
  location: { type: 'point' },
  established: { type: 'date' }
})

当然,它们与流畅的搜索界面完美匹配

const studios = await studioRepository.search()
  .where('established').after(date)
  .return.all()

const studios = await studioRepository.search()
  .where('location').inRadius(
    circle => circle.origin(-81.7758995, 41.4976393).radius(50).miles)
  .return.all()

更好得集成 Node Redis

我 Node.js 的 Redis OM 中最喜欢的更改可能是它与 Node Redis 的工作方式。在预览版本中,你可以 .open 一个在后台使用 Node Redis 的客户端

const client = new Client()
await client.open('redis://#:6379')

现在,你可以 .use 从 Node Redis 现有的连接

import { createClient } from 'redis'

const redis = createClient('redis://#:6379')
await redis.connect()
const client = await new Client().use(redis)

这让你可以用 各种方式 连接到 Redis,而不仅仅是使用简单的连接字符串。我还更改了 .open 和 .use 以返回 Client,以便允许简洁的单行代码

const client = await new Client().open('redis://#:6379')

一些重大更改

没有一个预览版是完美的;这就是它成为预览版的缘故。通过观察人们在使用 Node.js 的 Redis OM 时犯的错误,我学到了很多。这些错误是由于误解了 Redis OM 界面部分所致。我需要改进这些部分,因为我对它们的思考还不够透彻。这些改进带来了一些重要但重大的更改。

重命名一些类型

我注意到很多人在使用 string 作为 RediSearch 中的 TEXT 而不是 TAG 时都会感到困惑。所以我明确地做出了此种区分,将字符串类型拆分为两个类型:stringtext

我还了解到 array 类型只能是一个字符串数组这一事实尚不清楚。我将其更改为 string[]

let albumSchema = new Schema(Album, {
  artist: { type: 'string' },
  title: { type: 'text' },
  year: { type: 'number' },
  genres: { type: 'string[]' },
  outOfPublication: { type: 'boolean' }
})

JSON 是默认值

几乎所有使用 Redis OM 的人都同时使用了 RediSearch RedisJSON。他们选择将其文档存储为 JSON 文档。但在预览中,Redis OM 使用哈希作为默认存储机制。

导致每个人都必须明确地告诉 Redis OM 使用 JSON

let albumSchema = new Schema(Album, {
  artist: { type: 'string' },
  title: { type: 'string' },
  year: { type: 'number' },
  genres: { type: 'string[]' },
  outOfPublication: { type: 'boolean' }
}, {
  dataStructure: 'JSON'
})

为了避免此步骤,我更改了默认值

let albumSchema = new Schema(Album, {
  artist: { type: 'string' },
  title: { type: 'string' },
  year: { type: 'number' },
  genres: { type: 'string[]' },
  outOfPublication: { type: 'boolean' }
})

无论如何,你们都在使用 JSON,所以此更改实际上并不会影响太多开发人员。但是,现在可以额外删除一些代码了,这真的很好!

软件永远没有完成的一天

当然,软件永远不会完成。我想添加到 Redis OM 的东西比我可能没时间实现的东西更多。以下是未来版本中我关注的几件事

  • 可嵌入实体:这显然是最受请求的功能。现在,实体是扁平的。无法在 JSON 中使用 Redis OM 创建嵌套对象。我正在编写这篇博文时处理此事。很快就会出来。
  • 自带密钥:这是另一项很受欢迎的请求。创建实体时,Redis OM 会生成一个密钥,将其称为实体 ID。但你通常已经有一个想要使用的主键。我可能会在可嵌入实体后解决此问题。
  • 装饰器:我想使用装饰器,以便可以注释架构中的信息。TypeScript 有它们,虽然它们仍然是“实验性的”,但如果 Next.js 使用装饰器已经足够了,那么对我来说可能也足够了。也许JavaScript也很快就会获得它们。对于 Node.js 的 RedisOM,这可能是一个 2.0 特征。

一些有用的资源

如果你刚开始使用 Redis OM,我也一直在处理一些有用的内容

  • 我使用 Express 和 Redis OM 编写了一个简单的示例 API。把它当作一个初始代码。Fork 它,进行更改,然后开始。
  • 我汇编了一个视频教程,引导你使用 Express 和 Redis OM 构建 API。从本质上讲,这是上述的 starter code,但它引导你构建 API。
  • 所有新特性和旧特性均记录在README中。如果你想知道如何做某事,它可能就在那里。
  • 如果你遇到困难,我经常在Redis Discord服务器上。可能比健康状况更多。好好利用它!
  • 我以及一些同行通过流媒体方式传播各种内容(包含很多 Redis OM 和 Redis Stack 内容)——在 Twitch 网站上。到那里观看我们的直播吧。

谢谢

那么,怎样总结 Redis OM for Node.js 的新内容呢?Redis OM 得益于社区人员的帮助才取得了今天的成绩,因此我愿意衷心地对那些曾提供了帮助……的确提供了帮助的人表示感谢。

  • Aviv Ben Yosef 提交了来自 Redis 以外人员的第一个 PR。
  • Benjamin Winkler 对 README 做出了改进。
  • Dani Patko 实现 .sortBy、.min 和 .max。
  • DidaS 在提高 Redis OM 性能和代码质量方面提供了所有帮助。他帮助了其 linter。
  • Lucthat rando 提议的更改做出了修改。并且他还提供了热情洋溢的支持。
  • Simon Green 使测试套件的处理速度提高了几个数量级。
  • 我的好朋友 Nilanjan,他竟然敢在生产中使用预览软件,并提供了大量的反馈。Fortuna audentes iuvat

我肯定遗漏了一些人,但要知道,GitHub 的提交历史永远不会忘记。