node.js - 如何从 FaunaDB 的集合中获取所有文档?
问题描述
我已经有了答案:
const faunadb = require('faunadb')
const q = faunadb.query
exports.handler = async (event, context) => {
const client = new faunadb.Client({
secret: process.env.FAUNADB_SERVER_SECRET
})
try {
// Getting the refs with a first query
let refs = await client.query(q.Paginate(q.Match(q.Index('skus'))))
// Forging a second query with the retrieved refs
const bigQuery = refs.data.map((ref) => q.Get(ref))
// Sending over that second query
let allDocuments = await client.query(bigQuery)
// All my documents are here!
console.log('@allDocuments: ', allDocuments);
//...
} catch (err) {
// ...
}
}
但我觉得它不令人满意,因为我正在对似乎最微不足道的数据库调用进行 2 次查询。对我来说,这似乎效率低下且冗长。
因为我刚刚了解 FaunaDB,所以这里可能有些东西我没有掌握。我的问题可以分为3个:
- 我可以在一次调用中查询所有文档吗?
- 如果不是,为什么不呢?这样的设计背后的逻辑是什么?
- 我可以在没有索引的情况下进行这样的查询吗?
解决方案
FaunaDB 的 FQL 语言与 JavaScript 非常相似(如果您想做条件事务等,这很有帮助)。
本质上,FaunaDB 也有一个 Map。鉴于您的索引仅包含一个作为参考的值,您可以这样写:
q.Map(
q.Paginate(q.Match(q.Index('skus'))),
q.Lambda(x => q.Get(x))
)
对于这种特定情况,您实际上不需要索引,因为每个集合都有一个内置的默认索引,可以通过“文档”功能进行全选。
q.Map(
q.Paginate(Documents(Collection('<your collection>'))),
q.Lambda(x => q.Get(x))
)
现在,如果您使用的索引返回多个值(因为您想要对“ref”以外的其他内容进行排序),那么您需要向 Lambda 提供与在指数。假设我的索引中有ts和ref值,因为我想按时对它们进行排序,那么获取所有值的查询变为:
q.Map(
q.Paginate(q.Match(q.Index('<your index with ts and ref values>'))),
q.Lambda((ts, ref) => q.Get(ref))
)
值用于范围查询/排序,但也定义索引返回的内容
回到你的问题:
- 我可以在一次调用中查询所有文档吗?
当然,我建议你这样做。请注意,您将获得的文档会自动分页。您可以通过提供参数来设置页面大小以分页,如果页面更大,将返回“之后”或“之前”属性。之后或之前可以再次作为参数呈现给 Paginate 函数以获取下一页或上一页:https ://docs.fauna.com/fauna/current/api/fql/functions/paginate
- 我可以在没有索引的情况下进行这样的查询吗?
不,但您可以使用上述内置索引。FaunaDB 保护用户免于在没有索引的情况下进行查询。由于它是一个可扩展的数据库,可以包含大量数据并且是现收现付的,因此防止用户在脚下开枪是个好主意:)。分页和强制索引有助于做到这一点。
至于为什么 FQL 不同。FQL 是一种不像许多查询语言那样具有声明性的语言。相反,它是程序性的,您可以准确地编写获取数据的方式。这有以下优点:
- 通过编写如何检索数据,您可以准确预测查询的行为方式,这在现收现付系统中非常有用。
- 相同的语言可用于安全规则或复杂的条件事务(根据某些条件更新某些实体或跨越不同集合的许多实体)。在 Fauna 中编写一个在一个事务中执行许多操作的查询是很常见的。
- 我们称为用户定义函数的“存储过程”风格只是用 FQL 编写,而不是另一种语言。
本教程中还讨论了查询,该教程附带 GitHub 存储库中的代码,这可能会给您一个更完整的画面:https ://css-tricks.com/rethinking-twitter-as-a-serverless-app/
推荐阅读
- pine-script - 锚定的 vwap 不会在条件下开始绘图
- vbscript - 打开带有指定 url 和指定浏览器的链接,用 vbscript 隐藏
- api - 如何从公司网址获取 ASX 股票代码?
- reactjs - 访问上传的 react-dropzone 文件
- nexus - 如何通过 api 在 nexus 中获取包的创建时间
- javascript - Vue多选-根据选择显示列表
- python - 将具有一个元素的列表更改为元组
- python - 我在 MapView 中遇到 MapMarker 问题
- postgresql - 手动接收 id 值后如何增加序列号?
- mysql - 在 Excel 中使用 if 语句进行参数化查询