2017-03-17 26 views
0

我看起來像這樣的三個表,班級,課程和userSchedules:RethinkDB:​​外部聯接從表到陣列

{ "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..." }

userSchedules { "userId": "123", "classes": [ "24ab7b14-f935-44c1-b91b-8598123ea54a", "ab7b4414-a833-4ac2-c84a-98123ea54a97" ] , }

我想寫加入開班授課(上courseNumber),然後外加入到userSchedules查詢。所以我想總是返回所有的類和相應的課程,如果用戶註冊了該類,我想返回。所以我想結果看起來像這樣:

{ "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")即使有從外沒有「右」側聯接總是返回true。是否有更好的方法來做到這一點:

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不工作。我已經編輯了上述查詢以顯示我最近的努力。

回答

2

如果你只想讓你的查詢更具可讀性,你可以把它改成這樣:

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')) 
     }) 
    ) 
) 
+0

我,使這個查詢非常複雜的另一個挑戰。我現在想要獲得每個班級註冊的學生人數。對於每個類,這將是userSchedules.classes數組中具有該classId的用戶數。挑戰是這將是一個聚合,但我仍然需要知道當前用戶是否註冊。有沒有辦法做到這一點,而不做2個查詢?爲了使其更具挑戰性,我想聽取這些變化,以便我可以實時更新班級可用座位的數量。 –

+0

也許在這一點上,我應該停止使用的陣列,使連接更容易和/或更好的性能? –

+0

這會使查詢變得更加複雜,因爲在連接上沒有更換。有幾種方法。 一種方法是創建一個「物化視圖」表將容納所有你想要的信息,你將使用偵聽來自其他表changefeeds它填補,它可能是一個有點昂貴。另一種方法是在迭代中通過前一個查詢的無限遊標進行查詢,但這太複雜了,無法在註釋中顯示。 – RonZ