执行嵌套 filter/join

Performing a nested filter/join

我有 3 张桌子。 forums,其中有许多 posts,其中有许多 comments。我想从一个特定的 forum 中检索所有 comments。我知道我可以将以下内容作为单独的查询执行:

var chosenForumID = "...";
var posts = /* get all posts where post.forumID === chosenForumID */;
var comments = /* get all comments where comment.postID is in 'posts' */; 

虽然可以使用一个嵌套查询吗?

朴素的方式

您实际上可以通过执行以下操作在一个查询中完成此操作:

r.table('forums')
 .get(ID)
 .merge({
   'comments': r.table('posts').filter({ 'forumID': ID })('id').coerceTo('array')
      .do(function (postsIdsArray) {
        return r.table('comments').filter(function (row) {
           return postsIdsArray.contains(row('id'));
        })
      }).coerceTo('array')
 })('comments')

更好的方式

如果您经常执行此操作并且您在 child 上有关系(child 有一个 parent 属性 指向 ID),那么您应该为 forumIDpostID 创建二级索引。

// Create Indexes
r.table('posts').indexCreate('forumId')
r.table('comments').indexCreate('postId')

创建它们之后(您只需创建一次),然后您可以使用 getAll 术语使其成为索引操作。

r.table('forums')
 .get(1)
 .merge({
   'comments': r.table('posts').getAll(1, { index: 'forumId' })('id').coerceTo('array')
      .do(function (postsIdsArray) {
        return r.table('comments').getAll(r.args(postsIdsArray), { index: 'postId' }).coerceTo('array')
      })
 })('comments')

二级索引使这个操作更快。