RethinkDB:从 Table 到数组的外部连接
RethinkDB: Outer Join from Table to Array
我有三个表,classes、courses 和 userSchedules,如下所示:
classes
{
"classId": "24ab7b14-f935-44c1-b91b-8598123ea54a",
"courseNumber": "PO101" ,
"days": "MWF" ,
"professor": "Abramius Darksbayn" ,
"seatsAvailable": 23 ,
"time": 11
}
课程
{
"courseNumber": "PO101" ,
"courseName": "Intro to Potions" ,
"creditHours": 3 ,
"description": "Potions..."
}
用户计划
{
"userId": "123",
"classes": [
"24ab7b14-f935-44c1-b91b-8598123ea54a",
"ab7b4414-a833-4ac2-c84a-98123ea54a97"
] ,
}
我想编写一个连接 classes 和课程(在 courseNumber 上)然后外连接到 userSchedules 的查询。所以我想总是 return 所有 classes 和他们相应的课程加上我想 return 如果用户注册了那个 class。所以我希望结果看起来像这样:
{
"classId": "24ab7b14-f935-44c1-b91b-8598123ea54a",
"days": "MWF" ,
"professor": "Abramius Darksbayn" ,
"seatsAvailable": 23 ,
"time": 11,
"course": {
"courseNumber": "PO101" ,
"courseName": "Intro to Potions" ,
"creditHours": 3 ,
"description": "Potions..."
},
isEnrolled: true
}
我真的很难弄清楚如何让这项工作发挥作用,其次,最有效的方法是什么。任何帮助将不胜感激!谢谢!
编辑
好的,我找到了一种方法来完成大部分工作,但看起来确实有很多代码而且我也想知道它的性能。 并且 !!result("right")
始终 return 为真,即使外部连接没有 "right" 一侧。 是否有更好的方法来执行此操作:
r.table('classes')
.eqJoin('courseNumber', r.table('courses'))
.outerJoin(
r.table('userSchedules').getAll(userId).concatMap(schedule => schedule('classes')),
(joinedClass, scheduledClassId) => joinedClass('left')('classId').eq(scheduledClassId))
.map(result => {
return {
classId: result('left')('left')('classId'),
days: result('left')('left')('days'),
professor: result('left')('left')('professor'),
seatsAvailable: result('left')('left')('seatsAvailable'),
time: result('left')('left')('time'),
course: result('left')('right'),
enrolled: result.hasFields('right')
}
})
编辑 2:
我想通了为什么 isEnrolled 不起作用。我已经编辑了上面的查询以显示我最近的努力。
如果您只想让您的查询更具可读性,您可以将其更改为以下查询:
const allUserClasses =
r.table('userSchedules')
.getAll(userId)
.concatMap(schedule => schedule('classes'))
r.table('classes')
.eqJoin('courseNumber', r.table('courses'))
.map(joined => joined('left').without('courseNumber').merge({course: joined('right') })
.outerJoin(allUserClasses,
(joinedClass, scheduledClassId) => joinedClass('classId').eq(scheduledClassId))
.map(result => result('left').merge({ enrolled: result.hasFields('right') })
此外,如果你有一个固定的小数组,外部连接总是矫枉过正,这更合适:
r.table('userSchedules')
.get(userId)('classes')
.do(userClasses =>
r.table('classes')
.eqJoin('courseNumber', r.table('courses'))
.map(joined => joined('left')
.without('courseNumber')
.merge({
course: joined('right'),
enrolled: userClasses.contains(joined('left')('classId'))
})
)
)
我有三个表,classes、courses 和 userSchedules,如下所示:
classes
{
"classId": "24ab7b14-f935-44c1-b91b-8598123ea54a",
"courseNumber": "PO101" ,
"days": "MWF" ,
"professor": "Abramius Darksbayn" ,
"seatsAvailable": 23 ,
"time": 11
}
课程
{
"courseNumber": "PO101" ,
"courseName": "Intro to Potions" ,
"creditHours": 3 ,
"description": "Potions..."
}
用户计划
{
"userId": "123",
"classes": [
"24ab7b14-f935-44c1-b91b-8598123ea54a",
"ab7b4414-a833-4ac2-c84a-98123ea54a97"
] ,
}
我想编写一个连接 classes 和课程(在 courseNumber 上)然后外连接到 userSchedules 的查询。所以我想总是 return 所有 classes 和他们相应的课程加上我想 return 如果用户注册了那个 class。所以我希望结果看起来像这样:
{
"classId": "24ab7b14-f935-44c1-b91b-8598123ea54a",
"days": "MWF" ,
"professor": "Abramius Darksbayn" ,
"seatsAvailable": 23 ,
"time": 11,
"course": {
"courseNumber": "PO101" ,
"courseName": "Intro to Potions" ,
"creditHours": 3 ,
"description": "Potions..."
},
isEnrolled: true
}
我真的很难弄清楚如何让这项工作发挥作用,其次,最有效的方法是什么。任何帮助将不胜感激!谢谢!
编辑
好的,我找到了一种方法来完成大部分工作,但看起来确实有很多代码而且我也想知道它的性能。 并且 是否有更好的方法来执行此操作: !!result("right")
始终 return 为真,即使外部连接没有 "right" 一侧。
r.table('classes')
.eqJoin('courseNumber', r.table('courses'))
.outerJoin(
r.table('userSchedules').getAll(userId).concatMap(schedule => schedule('classes')),
(joinedClass, scheduledClassId) => joinedClass('left')('classId').eq(scheduledClassId))
.map(result => {
return {
classId: result('left')('left')('classId'),
days: result('left')('left')('days'),
professor: result('left')('left')('professor'),
seatsAvailable: result('left')('left')('seatsAvailable'),
time: result('left')('left')('time'),
course: result('left')('right'),
enrolled: result.hasFields('right')
}
})
编辑 2: 我想通了为什么 isEnrolled 不起作用。我已经编辑了上面的查询以显示我最近的努力。
如果您只想让您的查询更具可读性,您可以将其更改为以下查询:
const allUserClasses =
r.table('userSchedules')
.getAll(userId)
.concatMap(schedule => schedule('classes'))
r.table('classes')
.eqJoin('courseNumber', r.table('courses'))
.map(joined => joined('left').without('courseNumber').merge({course: joined('right') })
.outerJoin(allUserClasses,
(joinedClass, scheduledClassId) => joinedClass('classId').eq(scheduledClassId))
.map(result => result('left').merge({ enrolled: result.hasFields('right') })
此外,如果你有一个固定的小数组,外部连接总是矫枉过正,这更合适:
r.table('userSchedules')
.get(userId)('classes')
.do(userClasses =>
r.table('classes')
.eqJoin('courseNumber', r.table('courses'))
.map(joined => joined('left')
.without('courseNumber')
.merge({
course: joined('right'),
enrolled: userClasses.contains(joined('left')('classId'))
})
)
)