LoginSignup
0
0

More than 5 years have passed since last update.

ReQLでTableJoin(1対多)

Last updated at Posted at 2016-09-18

RethinkDBでtableJoinする方法について。

リファレンス

Table joins in RethinkDB

今回つかうテーブルとドキュメント

ユーザーテーブル

Screen Shot 2016-09-18 at 7.36.08 PM.png

メッセージテーブル

Screen Shot 2016-09-18 at 7.36.15 PM.png

ユーザーとメッセージは1対多の関係になっている。

ReQLクエリ

innerJoinを使った場合

ReQL command: innerJoin

r.db('DBName').table('messages').innerJoin(r.db('trialDB').table('users'), (messageRow, userRow) => {
  return messageRow('userId').eq(userRow('id'))
})

ちょっと長い。しかも、ドキュメントによると、innerJoinは遅いし効率が良くないので非推奨とのこと。(outerJoinも同様)

eqJoinを使った場合

ReQL command: eqJoin

r.db('DBName').table('messages').eqJoin('userId', 
r.db('DBName').table('users'))

短い。

クエリ結果

ちなみに、クエリ結果はこんな感じ。left, rightの項目にそれぞれのテーブルからマッチしたドキュメントが記載されている。

{
  "left": {
    "id": 3 ,
    "message":  "What's up?" ,
    "userId": 1
  } ,
  "right": {
    "id": 1 ,
    "name":  "Sam"
  }
} 

{
  "left": {
    "id": 1 ,
    "message":  "Hi, John" ,
    "userId": 1
  } ,
  "right": {
    "id": 1 ,
    "name":  "Sam"
  }
} 

{
  "left": {
    "id": 2 ,
    "message":  "Hi there, Sam" ,
    "userId": 2
  } ,
  "right": {
    "id": 2 ,
    "name":  "John"
  }
}

クエリ結果の整形

zipを使ってクエリ結果をマージ

ReQL command: zip

先程のeqJoinの末尾にzip()を付け足すと、クエリ結果のrightをleftにマージできる。

r.db('DBName').table('messages').eqJoin('userId', 
r.db('DBName').table('users')).zip()

↑のReQLを発行すると、以下の結果が取得できる。


{
  "id": 1 ,
  "message":  "What's up?" ,
  "name":  "Sam" ,
  "userId": 1
} 

{
  "id": 1 ,
  "message":  "Hi, John" ,
  "name":  "Sam" ,
  "userId": 1
} 

{
  "id": 2 ,
  "message":  "Hi there, Sam" ,
  "name":  "John" ,
  "userId": 2
}

ちょっとidがおかしなことになってます。

withoutをつかって不要な要素の削除

zipを使ってマージする前に、withoutを使ってrightドキュメントの結果からidを抜いておきます。

ReQL command: without

r.db('DBName').table('messages').eqJoin('userId',
r.db('DBName').table('users')).without({right: 'id'}).zip()

クエリ結果がきれいになりました。

{
  "id": 3 ,
  "message":  "What's up?" ,
  "name":  "Sam" ,
  "userId": 1
} 

{
  "id": 1 ,
  "message":  "Hi, John" ,
  "name":  "Sam" ,
  "userId": 1
} 

{
  "id": 2 ,
  "message":  "Hi there, Sam" ,
  "name":  "John" ,
  "userId": 2
}

idの順番が整列していなくて気持ち悪いです。

orederByで順序整理

orderByを使って、messageIdの順に整列させます。

ReQL command: orderBy

r.db('DBName').table('messages').eqJoin('userId',
r.db('DBName').table('users')).without({right: 'id'}).zip().orderBy('id')

zipの結果に対して並び替えを行うので、zipの後に追記しました。

クエリ結果がこちら。

{
  "id": 1 ,
  "message":  "Hi, John" ,
  "name":  "Sam" ,
  "userId": 1
} ,
{
  "id": 2 ,
  "message":  "Hi there, Sam" ,
  "name":  "John" ,
  "userId": 2
} ,
{
  "id": 3 ,
  "message":  "What's up?" ,
  "name":  "Sam" ,
  "userId": 1
}

きちんと整列しています。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0