Search code examples
rethinkdbreql

Building RethinkDB filter dynamically


I want to filter my data using filter specified as below:

var filter = { minAge: 2, maxAge: 11, country:'uk', city':'london'};

In which case the filtering will be:

r.db(dbName).table(tableName)
    .filter(r.row("minAge").ge(filter.minAge)
             .and(r.row("maxAge").le(filter.maxAge))
             .and(r.row('country').eq(filter.country))
             .and(r.row('city').eq(filter.city))
           );

However some of the filter predicates could be missing for example if I have only min age and city, I want to filter only on them:

var filter2 = { minAge: 2, city':'london'};

Above filter should result in below

r.db(dbName).table(tableName)
    .filter(r.row("minAge").ge(filter.minAge)             
             .and(r.row('city').eq(filter.city))
           );

How to build a ReQL query according to my filter object keys that I could pass to the filter function.


Solution

  • Sorry, I understand wrong and re-write my answer.

    I think what you can do is to write a generic function that run on client to return query for filter.

    First of all, if you are dealing with filter object dynamically, the filter function has no knowledge of which operation to apply. Given this:

    {city: 'London', minAge: 12}
    

    For city we want a eq, for minAge we want a ge but since we are doing this dynamically, it's prolly better to propose a syntax for filter object like this:

    {city: 'London', minAge: ['ge', 12]}
    

    With that in mind, I propose this solution:

    var filterObject = {
      minAge: ['ge', 12],
      city: 'london'
    }
    
    r.table('monitor').filter((function(filterObject) {
      var condition
    
      for (var key in filterObject) {
        var conditionForThisKey
        if (typeof key == 'string' || typeof key == 'number') {
          conditionForThisKey = r.row(key).eq(filterObject[key])
        } else {
          conditionForThisKey = r.row(key)[filterObject[key][0]](filterObject[key][1])
        }
    
        if (typeof condition === 'undefined') {
          condition = conditionForThisKey
        } else {
          condition = condition.and(conditionForThisKey)
        }
      }
    
      return condition
    })(filterObject))
    .run(connection)
    .then(function(cursor){ //do stuff with result })
    .error(function(err) { //err handling })
    

    This way, We build condition object for RethinkDB on client dynamically. I'm thinking that we can push that logic to RethinkDB with r.js. But I don't see a point to let that run on RethinkDB, client has capable of that.

    Let me know if this helps.