Search code examples
androidcouchdbcouchbase-lite

CouchDB filtering by date


On Android using CouchDB with CouchBase Lite I am trying to replicate a database also I use filter in order to get documents with a field whose name is device_number So I have this filter:

"1": "function(doc, req) {
  if(doc.ismaster || doc._deleted)
return false; 
  if( 1 == doc.device_num || 22 == doc.device_num || 25 == doc.device_num || 41 == doc.device_num )
return true;
  else 
return false;}", 

It works perfectly and I get all the documents for the devices: 1, 2 , 25 ,41.
Well now I want to get documents for device_num = 22 and 21 and whose creation_date has less than 60 days from the present day so I do:

 "1": "function(doc, req) {
      if(doc.ismaster || doc._deleted)
    return false; 
      if( 22 == doc.device_num && 21 == doc.device_num && (Math.ceil((new Date(Date.now()).getTime() - new Date(doc.creation_date.split('/')[2], doc.creation_date.split('/')[1] - 1, doc.creation_date.split('/')[0]).getTime()) / (1000 * 3600 * 24)) <= 60) )
    return true;
      else 
    return false;}", 

but I am not getting results, 0 documents, and is not true because in the database there are documents with less than 60 days.

what I am doing wrong?


Solution

  • I want to get documents for device_num = 22 and 21 and whose creation_date has less than 60 days from the present day

    English wording: "I want documents for 21 and 22" is actually "I'll accept any document where the document is for either 21 or 22":

           if( (22 == doc.device_num || 21 == doc.device_num) && ...)
    

    as no document with a single device_num can simultaneously be for devices 21 and 22.

    Dates are a bit of a mess around the world and who knows if your user's are in the same time zone? Couchdb provides some examples of considering collation factors in dates, and here is an example of using number type for safe collation:

     // creation:
     {tstamp:+new Date(), device_num:22, ...}
     // test
     validstamp = +new Date() - 1000*60*60*24*60;
     if( (22 == doc.device_num || 21 == doc.device_num) && Number(doc.tstamp) > validstamp)
         ...
    

    Its nice to use Number() in case something went wrong in storage and you have stored a string. But as numbers, they are logically sequential without oddities of non-zero padded strings around the early 1980s and the distant future and you can later refactor to using mango indexes with:

    {
      "tstamp": {'$gt':validstamp},
      "$or": [
          { "device_num": 21 },
          { "device_num": 22 }
      ]
    }