gristow
gristow

Reputation: 45

Filter for hits on two arrays in RethinkDB ReQL?

Given the table checkpointAttempts, with schema:

{ 
  id: primary_key,
  userId: secondary_key & index,
  checkpointId: secondary_key & index
}

I'm trying to find all of the checkpointAttempts matching both an array of userIds and an array of checkpointIds at runtime.

I thought it might work by doing this:

// var userIds and checkpointIds are defined arrays & in scope

var q = r.table("checkpointAttempts");
q = q.getAll.apply(q, userIds.concat({index: userId}))
  .filter(function(attempt){
    return checkpointIds.indexOf(attempt('checkpointId')) !== -1
  })
  .run(conn)

But, filter's predicate function seems to always return false.

Any suggestions as to what I'm doing wrong, or how I might construct this query differently?

Thanks!

Upvotes: 0

Views: 117

Answers (1)

kureikain
kureikain

Reputation: 2314

You cannot use raw JavaScript such as indexOf inside filter function. You have to use ReQL expression and function.

On getAll, you can to simply wrap all arguments with args, and remove the need of apply to pass argument as an array.

The right query is like this:

r.table('checkpointAttempts')
  .getAll(r.args(userIds), {index: 'userId'})
  .filter(function(attempt){
    return r.expr(checkpointIds).contains(attempt('checkpointId')).eq(true)
  })

Just want to post some JS code here to help you get a clear idea:

var r = require('rethinkdb')

userIds = [1,2]
checkpointIds = [14, 12]

r.connect().then(function(conn) {
  return r.table('checkpointAttempts')
  .getAll(r.args(userIds),{index: 'userId'})
  .filter(function(attempt){
    return r.expr(checkpointIds).contains(attempt('checkpointId')).eq(true)
  })
  .run(conn)
})
.then(function(cursor) {
  return cursor.toArray()
})
.then(function(d) {
  console.log(d)
})

Upvotes: 1

Related Questions