如何在 FaunaDB 中获取嵌套文档?
How to get nested documents in FaunaDB?
要在 Fauna 中获取单个文档,我们会这样做:
q.Get(q.Ref(q.Collection('posts'), '192903209792046592'))
我们得到类似的东西:
{
data: {
title: 'Lorem ipsum',
authorId: '892943607792046595'
}
}
是否可以在同一查询中获取 post 和作者?
像这样:
{
data: {
title: 'Lorem ipsum',
author: {
name: 'John Doe'
}
}
}
所以首先,最好在文档中存储 refs 而不是 ids。
在问题中存储示例 post 时,它应该是这样的(使用 JS 驱动程序):
{
title: 'Lorem ipsum',
authorRef: q.Ref(q.Collection("authors"), "1234556456858234")
}
然后要获得带有嵌套作者的 post,您需要使用 Let
.
创建自定义对象
它会是这样的(再次使用 JS 驱动程序):
q.Let(
{
postDoc: q.Get(q.Ref(Collection('posts'), '192903209792046592')),
authorRef: q.Select(['data', 'authorRef'], q.Var('postDoc')),
authorDoc: q.Get(q.Var('authorRef')),
},
{
title: q.Select(['data', 'title'], q.Var('postDoc')),
author: {
name: q.Select(['data', 'name'], q.Var('authorDoc')),
}
}
)
哪个 return:
{
title: 'Lorem ipsum',
author: {
name: 'John Doe'
}
}
另一种选择可能是 return 并排放置两个完整文档:
q.Let(
{
postDoc: q.Get(q.Ref(Collection('posts'), '192903209792046592')),
authorRef: q.Select(['data', 'authorRef'], q.Var('postDoc'))
},
{
postDoc: q.Var('postDoc'),
authorDoc: q.Get(q.Var('authorRef')),
}
)
由于这是一个常见问题,我将对其进行扩展并为您提供入门所需的所有信息。我最近写了一个例子,很快也会详细说明这一点。
我将逐步构建查询以尽可能地受教育
比方说..我们写了一个类似推特的应用程序并想要检索推文。
我们要做的第一件事就是获取推文列表。
首先..获取参考资料
Paginate(Documents(Collection('fweets')))
其中 return 是参考列表
...或索引值
Paginate(Documents(Index('some_index')))
其中 return 是您在创建索引时选择的所有值,例如:[[value1, value2], ...]
这将 return 一页参考文献,或者本质上是一个参考文献列表。
使用 Get
获取列表的实际文档
然后你做你在你的问题中所做的,你 Get 通过用 Map 映射它的引用(并且 Map 将是随着我们的进一步发展,您的主力将回答您的问题)
Map(
Paginate(Documents(Collection('fweets'))),
Lambda('ref', Var('ref'))
)
转换这些文档以获得其他数据(您的具体问题)
您可以使用与我们获取参考完全相同的技术,在文档上映射。只有现在我们才会对指向其他集合的引用执行 Get。想象一下,我的每个 Tweets 中都有一个 Author,让我们找到那个作者。我们将使用 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')
)
)
)
我们现在将添加一行以获取作者。
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')
}
)
)
)
这会 return:
[{
"fweet": {
< your tweet data >
},
"author": {
< your author data >
}
}, ... ]
既然我们有了这个结构,添加一些额外的东西就很容易了。想象一下,我们还有一条 'asset' 推文链接到我们将其 ref 存储在推文中的推文
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'),
}
)
)
)
当然..如果我们想要获取的东西不是存储的引用但我们想加入属性怎么办?那么想象一下,我们想要获取一条推文上的多条评论?这就是索引的用武之地!
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'))),
comments: Map(
Paginate(Match(Index('comments_by_fweet_ordered'), Var('f'))),
Lambda(
// my index has two values, I only need the comment reference but adding the ts makes them appear in order!
['ts', 'commentref'],
Get(Var('commentref'))
)
)
},
// And now we return a nested doc
{
fweet: Var('fweet'),
author: Var('author'),
asset: Var('asset'),
comments: Var('comments')
}
)
)
)
就像那样......您可以逐渐增加复杂性并进行非常复杂的查询。我的应用程序中的查询会像这样继续进行,以获取诸如推文统计信息之类的信息,如果是转推,甚至是原始推文
在 FQL 中实际上几乎没有什么不能做的:)
要在 Fauna 中获取单个文档,我们会这样做:
q.Get(q.Ref(q.Collection('posts'), '192903209792046592'))
我们得到类似的东西:
{
data: {
title: 'Lorem ipsum',
authorId: '892943607792046595'
}
}
是否可以在同一查询中获取 post 和作者?
像这样:
{
data: {
title: 'Lorem ipsum',
author: {
name: 'John Doe'
}
}
}
所以首先,最好在文档中存储 refs 而不是 ids。
在问题中存储示例 post 时,它应该是这样的(使用 JS 驱动程序):
{
title: 'Lorem ipsum',
authorRef: q.Ref(q.Collection("authors"), "1234556456858234")
}
然后要获得带有嵌套作者的 post,您需要使用 Let
.
它会是这样的(再次使用 JS 驱动程序):
q.Let(
{
postDoc: q.Get(q.Ref(Collection('posts'), '192903209792046592')),
authorRef: q.Select(['data', 'authorRef'], q.Var('postDoc')),
authorDoc: q.Get(q.Var('authorRef')),
},
{
title: q.Select(['data', 'title'], q.Var('postDoc')),
author: {
name: q.Select(['data', 'name'], q.Var('authorDoc')),
}
}
)
哪个 return:
{
title: 'Lorem ipsum',
author: {
name: 'John Doe'
}
}
另一种选择可能是 return 并排放置两个完整文档:
q.Let(
{
postDoc: q.Get(q.Ref(Collection('posts'), '192903209792046592')),
authorRef: q.Select(['data', 'authorRef'], q.Var('postDoc'))
},
{
postDoc: q.Var('postDoc'),
authorDoc: q.Get(q.Var('authorRef')),
}
)
由于这是一个常见问题,我将对其进行扩展并为您提供入门所需的所有信息。我最近写了一个例子,很快也会详细说明这一点。
我将逐步构建查询以尽可能地受教育 比方说..我们写了一个类似推特的应用程序并想要检索推文。 我们要做的第一件事就是获取推文列表。
首先..获取参考资料
Paginate(Documents(Collection('fweets')))
其中 return 是参考列表
...或索引值
Paginate(Documents(Index('some_index')))
其中 return 是您在创建索引时选择的所有值,例如:[[value1, value2], ...]
这将 return 一页参考文献,或者本质上是一个参考文献列表。
使用 Get
获取列表的实际文档然后你做你在你的问题中所做的,你 Get 通过用 Map 映射它的引用(并且 Map 将是随着我们的进一步发展,您的主力将回答您的问题)
Map(
Paginate(Documents(Collection('fweets'))),
Lambda('ref', Var('ref'))
)
转换这些文档以获得其他数据(您的具体问题)
您可以使用与我们获取参考完全相同的技术,在文档上映射。只有现在我们才会对指向其他集合的引用执行 Get。想象一下,我的每个 Tweets 中都有一个 Author,让我们找到那个作者。我们将使用 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')
)
)
)
我们现在将添加一行以获取作者。
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')
}
)
)
)
这会 return:
[{
"fweet": {
< your tweet data >
},
"author": {
< your author data >
}
}, ... ]
既然我们有了这个结构,添加一些额外的东西就很容易了。想象一下,我们还有一条 'asset' 推文链接到我们将其 ref 存储在推文中的推文
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'),
}
)
)
)
当然..如果我们想要获取的东西不是存储的引用但我们想加入属性怎么办?那么想象一下,我们想要获取一条推文上的多条评论?这就是索引的用武之地!
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'))),
comments: Map(
Paginate(Match(Index('comments_by_fweet_ordered'), Var('f'))),
Lambda(
// my index has two values, I only need the comment reference but adding the ts makes them appear in order!
['ts', 'commentref'],
Get(Var('commentref'))
)
)
},
// And now we return a nested doc
{
fweet: Var('fweet'),
author: Var('author'),
asset: Var('asset'),
comments: Var('comments')
}
)
)
)
就像那样......您可以逐渐增加复杂性并进行非常复杂的查询。我的应用程序中的查询会像这样继续进行,以获取诸如推文统计信息之类的信息,如果是转推,甚至是原始推文 在 FQL 中实际上几乎没有什么不能做的:)