如何在 FaunaDB 中获取嵌套文档?

Pie*_*ier 6 faunadb

要在 Fauna 中获取单个文档,我们执行以下操作:

q.Get(q.Ref(q.Collection('posts'), '192903209792046592'))
Run Code Online (Sandbox Code Playgroud)

我们得到类似的东西:

{
  data: {
    title: 'Lorem ipsum',
    authorId: '892943607792046595'
  }
}
Run Code Online (Sandbox Code Playgroud)

是否可以在同一个查询中获取帖子和作者?

像这样的东西:

{
  data: {
    title: 'Lorem ipsum',
    author: {
      name: 'John Doe'
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

Bre*_*oms 12

由于这是一个常见问题,我将对其进行扩展,并为您提供入门所需的所有信息。我最近写了一个例子,很快也会详细说明这一点。

我将逐步构建查询以尽可能具有教育意义 假设.. 我们编写了一个类似 twitter 的应用程序并想要检索推文。我们要做的第一件事就是获取推文列表。

首先..获取参考

Paginate(Documents(Collection('fweets')))
Run Code Online (Sandbox Code Playgroud)

它返回一个引用列表

... 或索引值

Paginate(Documents(Index('some_index')))
Run Code Online (Sandbox Code Playgroud)

它返回您在创建索引时选择的所有值,例如: [[value1, value2], ...]

这将返回一个页面的引用,或者本质上是一个引用列表。

使用 Get 获取列表的实际文档

然后你做你在你的问题中所做的,你通过用Map对其进行映射来获得参考(随着我们的进一步发展,Map 将成为你回答你的问题的主力)

Map(
   Paginate(Documents(Collection('fweets'))),
   Lambda('ref', Var('ref'))
)

Run Code Online (Sandbox Code Playgroud)

转换这些文档以获取其他数据(您的具体问题)

您可以使用与我们完全相同的技术来获取引用,映射文档。只有现在我们才会对指向其他集合的引用执行 Get。想象一下,我的每条推文中都有一个作者,让我们找到那个作者。我们将使用Let来构建我们的查询并逐步进行让我们首先使用 Let 重构我们的查询

Map(
  Paginate(Documents(Collection('fweets'))),
  // and in this function, the magic will happen, for now we just return the tweet.
  Lambda('f',
    Let({
        fweet: Get(Var('f'))
      },
      Var('fweet')
    )
  )
)
Run Code Online (Sandbox Code Playgroud)

我们现在将添加一行以获取作者。

Map(
  Paginate(Documents(Collection('fweets'))),
  // and in this function, the magic will happen
  Lambda('f',
    Let({
        fweet: Get(Var('f')),
        author: Get(Select(['data', 'author'], Var('fweet'))), // we get the author reference
      },
      // And now we return a nested doc
      {
        fweet: Var('fweet'),
        author: Var('author')
      }
    )
  )
)
Run Code Online (Sandbox Code Playgroud)

这将返回:

[{
   "fweet": {
      < your tweet data > 
    },
    "author": {
      < your author data >
    }
}, ... ]
Run Code Online (Sandbox Code Playgroud)

现在我们有了这个结构,添加一些额外的东西很容易。想象一下,我们还有一个“资产”推文链接到我们在推文中存储引用的推文

[{
   "fweet": {
      < your tweet data > 
    },
    "author": {
      < your author data >
    }
}, ... ]
Run Code Online (Sandbox Code Playgroud)

当然......如果我们想要获取的东西不是存储的引用而是我们想要加入一个属性怎么办?那么想象一下,我们对想要获取的推文有多个评论吗?这就是索引的用武之地!

Map(
  Paginate(Documents(Collection('fweets'))),
  Lambda('f',
    Let({
        fweet: Get(Var('f')),
        author: Get(Select(['data', 'author'], Var('fweet'))), 
        asset: Get(Select(['data', 'asset'], Var('fweet')))
      },
      // And now we return a nested doc
      {
        fweet: Var('fweet'),
        author: Var('author'),
        asset: Var('asset'),
      }
    )
  )
)
Run Code Online (Sandbox Code Playgroud)

就像那样......你可以逐渐增加复杂性并进行真正复杂的查询。我的应用程序中的查询继续这样获取诸如推文统计信息或什至是原始推文(如果它是转推的话)之类的内容实际上在 FQL 中您几乎没有什么不能做的 :)