要在动物区系中获取单个文档,我们要做:
q.Get(q.Ref(q.Collection('posts'), '192903209792046592'))
我们得到类似的东西:
{
data: {
title: 'Lorem ipsum',
authorId: '892943607792046595'
}
}
是否可以在同一查询中获取帖子和作者?
类似这样的东西:
{
data: {
title: 'Lorem ipsum',
author: {
name: 'John Doe'
}
}
}
答案 0 :(得分:7)
由于这是一个常见问题,因此我将对其进行扩展,并为您提供所有您需要入门的信息。我最近写了一个示例,很快将对此进行详细说明。
我将逐步构建查询以使其尽可能地受教育 比方说..我们编写了一个类似Twitter的应用程序,并希望检索推文。 我们要做的第一件事就是获取推文列表。
Paginate(Documents(Collection('fweets')))
返回引用列表
Paginate(Documents(Index('some_index')))
返回创建索引时选择的所有值,例如:[[value1,value2],...]
这将返回引用页面,或本质上是引用列表。
然后,您按照问题的方式去做,就可以通过 Map 在地图上进行映射来获取(而Map将是您回答问题的主要动力。进一步)
Map(
Paginate(Documents(Collection('fweets'))),
Lambda('ref', Var('ref'))
)
您可以使用与获取参考文献,在文档上进行映射完全相同的技术。只有现在,我们才对指向其他集合的引用执行Get操作。想象一下,我的每个推文中都有一个 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')
}
)
)
)
这将返回:
[{
"fweet": {
< your tweet data >
},
"author": {
< your author data >
}
}, ... ]
现在我们有了这个结构,添加一些额外的东西很容易。想象一下,我们还有一个与该推文链接的“资产”推文,我们将其引用存储在推文中
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')
}
)
)
)
就像这样..您可以逐渐增加复杂性并执行真正复杂的查询。我的应用程序中的查询会像这样继续进行,以获取诸如tweet统计信息甚至原始tweet(如果是转推)之类的信息 在FQL中实际上没有什么可以做的:)
答案 1 :(得分:3)
因此,首先,最好将引用存储在文档中,而不是id中。
在问题中存储示例帖子时,应该是这样的(使用JS驱动程序):
{
title: 'Lorem ipsum',
authorRef: q.Ref(q.Collection("authors"), "1234556456858234")
}
然后使用嵌套的作者来发帖,您需要使用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')),
}
}
)
哪个会返回:
{
title: 'Lorem ipsum',
author: {
name: 'John Doe'
}
}
另一种选择是简单地并排返回两个完整文档:
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')),
}
)