0

on the concatMap api page in RethinkDB website, it's saying eqJoin is implemented with concatMap + getAll, which should provide better performance than other joins.

in my case, I'd like to join multiple tables, here's an example, let's assume I have 3 tables, users, departments and companies. in every user document would contain a department id and company id. eg:

var user = {
  name: 'Peter',
  company: '12345',
  department: '8888',
  otherDetails: 'abc 123'
}

the result I'd like to get after the join query is very similar to the result of a concatMap/eqJoin, but with all 3 tables:

[{
  user: {...},
  company: {...},
  department: {...}
}, ...]

here is a query I've written that could get the result:

r.table('users')
  .concatMap(function(user) {
    return r.table("companies").getAll(
      user("company")
    ).map(function(company) {
      return { user: user, company: company }
    })
  })
  .concatMap(function(row) {
    return r.table("departments").getAll(
      row("user")("department")
    ).map(function(department) {
      return { user: row("user"), company: row("company"), department: department }
    })
  })

my questions:

  1. is there a better way to do this?
  2. is the performance of the above query still as good as usual eqJoin on 2 tables?
  3. is the performance of using merge much worse than using eqJoin (concatMap) in these cases?

thanks much.

oldlam
  • 13
  • 5

1 Answers1

0
  1. That looks like the best way to do it to me. If you wanted you could move the second concatMap into the first .concatMap (so you chain it onto the end of getAll). That might be faster, you'd have to benchmark it to find out, but it should be roughly the same speed.

  2. Yes, it should be.

  3. I don't think you can do this task with merge. Any time you want to turn one input row into multiple output rows you need to use concatMap or a join. If instead of one output document per user/company/department pair you want one output document per user with arrays of companies and departments in them, then merge could be used for that and should be roughly the same speed (or if anything a tiny bit faster).

mlucy
  • 5,249
  • 1
  • 17
  • 21
  • thanks a lot Michael!! // 1. i'm moving `concatMap`s together cos it would be shorter (one `map` only) and more consistent to me (vars inside the `map`) // 2. perfect!! // 3. i got what you mean, `concatMap` is returning exactly what i need for this case now. gonna read more stuffs about `merge` vs `concatMap` in RethinkDB, and think clear about what i have to do before seeking help again. // thanks so much again for the quick answer!! :) – oldlam Sep 19 '15 at 19:30