Android and LiveQuery - Advice/best-practise for filtering

I know dude, just wanted to be sure i understood correctly :wink:

Regards,

Hello Jens,

How to skip a row inside an iteration ?

Here is my code (JAVA), i would like to mark a row 'of the results to be skipped before displaying them on phone.

for (Iterator<QueryRow> it = result; it != null && it.hasNext(); ) {
    QueryRow row = it.next();

        user = row.getDocument();
        Log.i(TAG, "User emitted in Matches" + user);

        if (checkUserIsOnline(user))
        {
            Log.i(TAG, "User is not online since 3 min - " + row.getValue() + "for key: " + (String) row.getKey());
            HERE --** I WANT TO SET A ROW AS SKIPPED ! ****
        }
    }

‘user’ variable is a Document.

Thanks

I think you’re asking how to delete a row from a query enumerator. You can’t; query enumerators are immutable.

To skip a row during iteration, just put an “if” test in the loop that’s doing the iteration. That means you’d have to modify the code that’s displaying the table, sounds like. Either that, or copy the query rows into an array, skipping the ones you don’t want, and then pass that array to the code that displays the table.

That’s exactly it.

So basically, if i have a key in a doc that contains date and time (for example : 28/09/2015 5:40 PM).
And i want to only get the document for those this date/time is the last 3 mins from the actual moment.

like : if ((DateTimeNOW-DateTimeDOC) < 3 min)

I can’t do it in the map function as it has to be a pure function.

So i have no choice than doing this in my iteration.

Correct ?

You can emit DateTimeDOC as the key, then set query.startKey = DateTimeNOW - 3min. (Obviously you convert the dates to strings first.)

If you really need the enumerator to rows based on criteria you can’t express in a query, on iOS you can add a postFilter to the query. This is a block that can look at each row and return true/false; if it returns false the row is skipped.

Hmm, i am already emitting a doc like this in my map function :

emitter.emit(document.get("key1"), document.get("userId")) ;

And then i filter just before iteration like this :

query.setKeys(key1);

Can i add DateTimeDOC as the key also ?

Are you sure this will works if i want ALL documents for which the ‘DateTime’ value is between NOW and the last 3 mins ?

For example, actual time is 10.00 PM, i want all documents for which ‘DateTime’ valueis betwee, 9.57pm and 10.00pm.

Yes, please see the docs on keys and values in map functions. Basically the first array element is the primary key, the second is the secondary key, etc.

Are you sure this will works if i want ALL documents for which the ‘DateTime’ value is between NOW and the last 3 mins ?
For example, actual time is 10.00 PM, i want all documents for which ‘DateTime’ valueis betwee, 9.57pm and 10.00pm.

Um, why wouldn’t it? If the key in the index is the date, and the startKey is a date 3 minutes ago, then you’ll get all docs whose emitted dates are after that time.

I have a feeling you’re not really understanding what an index is or how it works. Have you read the view and query documentation fully?

Thanks, this link was useful indeed.

I understand perfectly what an index is.

My difficulties are more around the query filtering and results handling. But you provided me nice answers here. I appreciate it.

Following your advices, i made a new index : i added a new key (String) that is representing the date ( Example 2015-09-30T03:23:35.230Z)

Then i use query.setStartKey(DateTimeNOW - 3 Min), of course as a String value (Example : 2015-09-30T03:20:35.230Z).

But my Query isn’t returning any row now.

Do you have an idea ?

Even if you are not JAVA, here is my code :

  public void map(Map<String, Object> document, Emitter emitter) {

                      
         List<Object> key = new ArrayList<Object>();         //use a list as key for indexing doc in view
             key.add(document.get("key1"));
             key.add(document.get("key2"));
             key.add(document.get("key3"));;
             key.add(getLastUpdateTimeUTC( (String) document.get("userinfo") ));
             emitter.emit(key, document.get("userId")) ;
                }
            }
        };
        view.setMap(map, "5");
    }

    /* ---------------CREATE the Query Object --------------*/

    Query query = view.createQuery();
    java.util.List<Object> keys = new ArrayList<>();
        keys.add("key1");
        keys.add("key2");
        keys.add("key3");
    query.setKeys(keys);
    query.setStartKey(calculateTimeItWas3MinAgo().toString());

The methods ‘getLastUpdateTimeUTC()’ and ‘calculateTimeItWas3MinAgo().toString()’ are returning the appropriate Strings…so the dates with time in the pattern “2015-09-30T03:23:35.230Z”.

Did i forgot something ?

You can’t combine startKey with keys. Use one or the other.

  • startKey and/or endKey specify a key range.
  • keys specifies a set of exact keys that you want.