Repeat query every X minutes

query
java
n1ql

#1

Hi,
Environment: Android
Couchbase lite version: 2.0.0-DB021

Suppose we have a query getAllDocuments() that selects all my documents. This query is called onStart() of my application.
I’d like to add a where filter that selects only the document with created_at field greater that the actual time.

For example, if now it was “2018-01-10T10:00:00”, a document with created_at = “2018-01-10T10:00:00” should be selected, instead a document with created_at = “2018-01-10T10:15:00” should not.

My actual query is:

Query.select(SelectResult.all())
                .from(DataSource.database("my_db"))
                .where(Expression.property("created_at").greaterThan(ACTUAL_TIME)

My first thought was to add an internal timer in android that run the query every X minutes.
My question is if there is a way to instruct couchbase to run a determinate query every X interval without using an external timer.

Thanks


#2

No, this is something that is out of the scope of Couchbase Lite and should be handled by your app logic.

You could use a parameterized Query with setParameters to change the ACTUAL_TIME value every time you run the query.

That said, I am not clear on your example.

In your example , you state that "a document with created_at = “2018-01-10T10:15:00” should not …be returned " but since the created_at value of document is greater than now = 2018-01-10T10:00:00, that document will be selected. In your example query, you are requesting for all documents with created_at greater than ACTUAL_TIME .

Also, have you considered a liveQuery ? For instance, You could use a LiveQuery that will automatically notify you whenever there is a change to the database that affects the results of your query.


#3

Ok, thank you very much. I apologize, the example was wrong, but you understand anyway the problem. I’ll check out live query. Thanks again


#4

Anything on how to use parameters in order to get greater than now?


#5

Hi,
in my case i simply use a where statement comparing a date ISO format with Date.now()


#6

You use the live query?


#7

No,
i used a Handler docs, that runs the query every X time.
Maybe live query is a better approach, but in my case i need to run different queries, so i decide to use a simple timer.


#8

Thanks
Thanks
Thanks


#9

This is an example of parameterized queries. Any time you change the parameters provided to a query , it will auto restart the query

  Query q1 = QueryBuilder
                .select(SR_NUMBER1)
                .from(dataSource)
                .where(dateParam.greaterThanOrEqualTo(Expression.date(new Date())))
                .orderBy(ordering);
        Parameters params1 = new Parameters(q1.getParameters()).setValue("currDate", myDate);
        q1.setParameters(params1);

Yes, you can make this a live query by attaching listeners and in your callback you can update the values


liveQuery remains alive
#10

Your example is unclear.
If I save a document with setLong(“currDate” ,1233456) for example, the param name should be “currDate” ?
dataParam is Expression.property(“currDate”)?
q.getParameters() is q1.getParameters()?


#11

Yes. That would be property name. But you can use setDate for dealing with Date values

q.getParameters() is q1.getParameters()?

Yes. Its q1. Edited the original post


#12

Ok, I’ll test it tomorrow morning


#13

I’m sorry pryia, it’s not working.
changed() is called but queryChange.getResults() is null.

The error:
CouchbaseLiteException{domain=1, code=34, msg=Unknown query property ‘db_update_time’}
It is funny because without the line
Parameters params1 = new Parameters(mQuery.getParameters()).setValue( “db_update_time”, lastSelectedTime);

It’s working. The onchange() is called without null.

And it is also funny because the where expression is
Expression.property( “db_update_time”).greaterThan(Expression.longValue(lastSelectedTime))

Are you sure you tested it? You sure it’s working the whole thing with the paramertes?


#15

The parameter should be used in place of a hardcoded value so

Expression.property( “db_update_time”).greaterThan(Expression.longValue(lastSelectedTime))

should be

Expression.property( “db_update_time”).greaterThan(dateParam)

Making some assumptions about the naming here, but in this case it would be a property on the document called ‘db_update_time’ and it would be compared to dateParam which would be something like Expression.Parameter("db_update_time_param"). In that case, you would set the “db_update_time_param” key on the parameters object on the query and each time you run the query it will consult the value contained in parameters.


#16

Please let me clarify.
Each saved document has “db_update_time” set:
newDoc.setLong("db_update_time" ,System.getcurrentMills());

So when I create the query object, I build it with the where expression:

Expression where = Expression.property("db_update_time").greaterThan(Expression.longValue(System.getcurrentMills()));

So, every time changed() is called, I wish to update this parameter.
I’m not sure what is dateParam in this exapmle and what is “db_update_time_param”


#17

Ok Got it now!
I understood it now.
It should be well documented

Thank you so much for your help.


#18

Since I typed up all of this and right before I finished I got your answer saying you understand I am posting it anyway in case others still do not

Let’s take this block of code as an example. What it is doing is setting up a query equivalent to this:

SELECT number1 FROM db WHERE number1 BETWEEN $num1 $num2 ORDER BY number1

In this example, num1 and num2 are “parameters” (you can think of them as variables in the mathematical sense). So whenever you run this query, you need to have associated data defining what the value of num1 and num2 is.

The cblite way to create num1 and num2 in this case in the query builder is to use Expression.parameter("num1") and Expression.parameter("num2") which corresponds to $num1 and $num2 above. However, as I mentioned you need to assign a value to these parameters before you run the query. That is where the Parameters class on the query object comes in. You will need to set a value in here for num1 and num2 before the query can work:

Parameters params1 = new Parameters(mQuery.getParameters()).setInt(“num1”, 3).setInt("num2", 5);
mQuery.setParameters(params1);

The next time you run the query, you don’t need to construct the whole thing again, you simply need to change the parameters and re-run and the new values inside the parameters will be used.


#19

I should have probably shared this link before but I assumed you were aware of the blogs . You can refer to this blog post. Examples are in swift but should be very straightforward to map to other languages.

That blog post also includes links to other querying capabilities if you are interested.