如何跨表执行嵌套属性的 join/merge?

How can I perform a join/merge of a nested attribute across tables?

我有一个 table(数据库名称是 libstats,table 名称是 flowcells),里面装满了文档,所有文档的结构如下:

{
        "barcode": "C3W9UACXX",
        "id": "0021732f-2c42-4e9a-90fd-c68bb0d998dc",
        "libraries": [
            {
                "bases": 2431000000,
                "library_id": "SL58263",
                "perc_raw_clusters": 5.5,
                "pf_reads": 24312986,
                "q30": 92.23,
                "qscore": 35.82,
                "reads": 25834646,
                "lane": 1
             },...
         ]
}

'libraries' 数组中的对象将始终显示键。我需要添加另一个键 library_name.

我在另一个数据库 libraries 中有另一个 table libraries,其中有此 library_name 信息。这是来自 table:

的示例文档
{
   library_id: 'SL123456',
   library_name: 'my_library_name'
}

如何使用 ReQL 来完成此操作?我已经走到这一步了:

r.db('libstats').table('flowcells').merge(function(flowcell){
  return {'libraries': flowcell('libraries').map(function(library){
    return library.merge(
       {'library_name': 'foo'}
      )
  })
  }
}).limit(1)

以我想要的结构给出输出,但是我使用 getFieldeqJoin()merge() 获取 library_name 属性的所有尝试都因此失败了事实证明毫无结果:

{
        "barcode": "C6841ANXX",
        "id": "007cae10-de3c-44df-9aee-1de9c88c1c21",
        "libraries": [
            {
                "bases": 194000000,
                "lane": "1",
                "library_id": "SL91807",
                "library_name": "foo",
                "perc_raw_clusters": 0.9,
                "pf_reads": 1942910,
                "q30": 96.55,
                "qscore": 36.06,
                "reads": 2045599
            },
        ]
    }

天真的实现

您可以执行以下操作:

r.db('libstats').table('flowcells').merge(function(flowcell){
  return {'libraries': flowcell('libraries').map(function(library){
    return library.merge({ 
      // Query the `libraries` table
      'library_name': r.db('libraries').table('libraries')
        // Filter out certain elements
        .filter(function (row) {
          // Return all elements where the `library_id` is equal to 
          // the `library_id` in the `libstats` table
          return row('library_id').eq(library('library_id'))
        })
        // Return the `library_name` for the first element
        (0)('library_name')
    })
  })
  }
})

请记住,您也可以为此使用二级索引,使它更简单、性能更高。

更好的解决方案

如果您有很多文档 (10K+),您需要在 library_id 上创建索引并使用以下查询:

r.table('libstats').merge(function(flowcell){
  return {'libraries': flowcell('libraries').map(function(library){
    return library.merge({ 
      // Query the `libraries` table
      'library_name': r.table('libraries')
        // Filter out certain elements
      .getAll(library('library_id'), { index: 'library_id' })(0)('library_name')
    })
  })
  }
})

这里是 简单实现 的简化版本,以防有人遇到类似问题:

r.db('libstats').table('flowcells').merge(function (flowcell) {
    return { libraries: flowcell("libraries").eqJoin("library_id", r.db("libraries").table("libraries") ).zip() };
})

(如果库中除了id和name还有其他字段,也会加入)