如何跨表执行嵌套属性的 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)
以我想要的结构给出输出,但是我使用 getField
、eqJoin()
和 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还有其他字段,也会加入)
我有一个 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)
以我想要的结构给出输出,但是我使用 getField
、eqJoin()
和 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还有其他字段,也会加入)