Node.js 如何从FaunaDB中的集合中获取所有文档?

Node.js 如何从FaunaDB中的集合中获取所有文档?,node.js,faunadb,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

我已经有了答案:

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) {
    // ...
  }
}
但我发现它并不令人满意,因为我正在为一个看起来最微不足道的DB调用进行两次查询。对我来说,这似乎效率低下而且冗长

因为我只是在学习FaunaDB,这里可能有一些我不懂的东西。 我的问题可以分为三个部分:

  • 我可以在一次呼叫中查询所有文档吗
  • 若否,原因为何?这种设计背后的逻辑是什么
  • 我可以在没有索引的情况下进行这样的查询吗

    • FaunaDB的FQL语言与JavaScript非常相似(如果您想执行条件事务等,这会有很大帮助)

      本质上,FaunaDB也有一张地图。鉴于您的索引只包含一个,您可以这样写:

      q.Map(
        q.Paginate(q.Match(q.Index('skus'))),
        q.Lambda(x => q.Get(x))
      )
      
      对于这种特定情况,实际上不需要索引,因为每个集合都有一个内置的默认索引,可以通过“Documents”函数执行全选

      q.Map(
        q.Paginate(Documents(Collection('<your collection>'))),
        q.Lambda(x => q.Get(x))
      )
      
      q.Map(
      q、 分页(文件(集合(“”)),
      q、 Lambda(x=>q.Get(x))
      )
      
      现在,如果您使用的索引返回多个值(因为您希望对“ref”以外的内容进行排序),那么您需要向Lambda提供与索引中定义的值数量相同的参数数量。假设我的索引中有tsref值,因为我想及时对它们进行排序,那么获取所有值的查询变成:

      q.Map(
        q.Paginate(q.Match(q.Index('<your index with ts and ref values>'))),
        q.Lambda((ts, ref) => q.Get(ref))
      )
      
      q.Map(
      q、 分页(q.Match(q.Index(“”)),
      q、 λ((ts,ref)=>q.Get(ref))
      )
      
      值用于范围查询/排序,但也定义索引返回的内容

      回到你的问题上来:

      -我可以在一次呼叫中查询所有文档吗?

      当然,我建议你这样做。请注意,您将获得的文档将自动分页。您可以通过提供一个参数进行分页来设置页面大小,如果页面较大,将返回“after”或“before”属性。after或before可作为参数再次显示给Paginate函数,以获取下一页或上一页:

      -我可以在没有索引的情况下进行这样的查询吗?

      不可以,但是您可以使用上面解释的内置索引。FaunaDB保护用户在没有索引的情况下进行查询。由于它是一个可伸缩的数据库,可能包含大量数据,并且是随用随付的,因此最好防止用户自食其果:)。分页和强制索引有助于做到这一点

      至于FQL不同的原因。FQL是一种不像许多查询语言那样是声明性的语言。相反,它是程序性的,您可以准确地编写获取数据的方式。这有以下优点:

    • 通过编写如何检索数据,您可以准确预测查询的行为,这在现收现付系统中很好
    • 相同的语言可用于安全规则或复杂的条件事务(根据特定条件更新某些实体或不同集合中的许多实体)。在Fanua中,编写一个查询在一个事务中完成许多事情是很常见的
    • 我们称为用户定义函数的“存储过程”只是用FQL编写的,而不是另一种语言
    • 本教程还讨论了查询,该教程附带了GitHub存储库中的代码,可以让您更全面地了解:

      我可以在一次呼叫中查询所有文档吗

      是的,如果你的藏品很少的话。
      Paginate
      函数默认为每页获取64个文档。您可以将页面大小调整到100000个文档。如果集合中的文档超过100000个,则必须执行多个查询,使用游标获取后续文档

      有关详细信息,请参见分页教程:

      若否,原因为何?这种设计背后的逻辑是什么

      对于SQL数据库,
      SELECT*fromtable
      既方便又可能成为资源噩梦。如果表包含数十亿行,则尝试为该查询提供结果可能会消耗服务器和/或客户端上的可用资源

      FaunaDB是一个共享数据库资源。我们希望查询对于任何数据库的用户都能很好地执行,这要求我们对任何单个事务中涉及的文档数量进行合理的限制

      我可以在没有索引的情况下进行这样的查询吗

      不,是的

      从FaunaDB检索多个结果需要索引,除非您独立跟踪文档的引用。但是,通过最近添加的
      文档
      功能(目前处于预览状态,因此不建议用于生产工作负载),我们现在维护了一个内部索引,这样您就不再需要创建自己的索引来访问集合中的所有文档

      有关详细信息,请参见文档参考页:

      回到您的示例代码,您正在执行两个查询,但它们可以很容易地组合成一个查询。FQL是高度可组合的。例如:

      let allDocuments = await client.query(
        q.Map(
          q.Paginate(q.Documents(q.Collection("skus"))),
          q.Lambda("X", q.Get(q.Var("X")))
        )
      )
      

      你对FQL冗长的观察是正确的。许多函数式语言都表现出这种冗长。优点是任何接受表达式的函数都可以随意组合。我们的电子商务教程中介绍了可组合性的最佳示例之一,以及如何管理文档间引用,特别是描述
      submit\u order
      函数的部分:

      嘿,你知道我如何在python中做到这一点吗?