3

I have a M-N relation of users and teams & I'm trying to use a subdoc strategy instead of a standard 3-table SQL strategy.

user = {
  id: 'user1',
  teams: [{'team1', roles: ['admin']}, {'team2', roles: ['editor']}]
}

team = {
  id: 'team1',
  name: 'The Team #1'
}

I'd like to grab the name field from the team table and stick it in the appropriate subdoc:

query = {
  id: 'user1',
  teams: [{'team1', roles: ['admin'], name: 'The Team #1'}, {'team2', roles: ['editor'], name: 'The Team #2'}]
}

I can get the team doc easily enough, but I keep overwriting the teams array:

//Query
    r.table('users').get('user1').merge(function(user) {
      return {
        teams: r.table('teams').getAll(r.args(user('teams')
            .map(function(team) {return team('id')}))).coerceTo('array')
      }
    })

//Bad result
user.teams = [
{
  "id":  "team1" ,
    "name":  "team 1"
} ,
{
  "id":  "team2" ,
    "name":  "team 2"
}
]

Is it possible to merge an array of objects based on an object field, or should I do this at the application level? Is there a better way?

Matt K
  • 4,813
  • 4
  • 22
  • 35

1 Answers1

2

If the teams array has the ID of the team, you can do something like this:

r.table('users').get('user1').merge(function(user) {
  return {teams: user('teams').merge(function(team) {
    return r.table('teams').get(team('id'));
  })};
})
mlucy
  • 5,249
  • 1
  • 17
  • 21
  • That works beautifully, thanks @mlucy! From a performance standpoint, it's about equally as expensive as a join, right? (obviously not important for this example, but for more frequent M-N queries) – Matt K Dec 10 '15 at 04:00
  • Yeah, it's about as expensive as a join, at least in the current version of RethinkDB. – mlucy Dec 10 '15 at 05:00