Need help in creating one single query which returns list and also does processing when no document found


#1

I have list of document ids for which I am doing bulk read using Observable using below code which returns a list of documents found:

I have to add 2 requirements here:

  1. If there is no document available in couchbase for any key, then I need to retry read operation again by changing the key(using Like operation with truncated key).
  2. If there is no document found after all retries then I need that key for further processing.

So after processing I should get list of documents found and list of keys for which document is missing.

I am not sure if it can be achieved using N1QL/View/Observables. Plz give me some pointers on how it can be achieved?

Many Thanks in advance.


#2

Hi, it can be achieve with Observables like this

List<JsonDocument> docs = Observable.from(ids).flatMap(id ->
      ab.get(id)
      .switchIfEmpty(ab.get(doSomethingwithId(id)))
      .defaultIfEmpty(null)
      .filter(doc -> {if ( doc == null ){ idsNotFound.add(id);return false;} else {return true;}})
     )
   .toList().toBlocking().single();

#3

Many Thanks Laurent,

@ldoguin Since we are using JDK 1.6 in our application I can not use Lambada expressions. But I am stuck at filter operator. As per my understanding we can have one input and one output for every function in flatmap. But in filter you are using 2 inputs i.e. doc and id and output is Boolean. Can you plz let me know how can I get the handle of document in Filter operator.

Thanks in advance.


#4

@ldoguin, Can you plz also confirms that operators switchIfEmpty, defaultIfEmpty and filter will be inside flatMap? And I am getting beloww error in switchIfEmpty:

This is my updated code:

Can you plz tell me where I am making mistake.

Thanks in advance.


#5

Hi,

switchIfEmpty takes an object, not a function, so you can put dsBucket.async().get(retryGetWithNewKey(id)) directly.
and yes they are all inside the flatMap as you need to keep a reference to the id.


#6

@ldoguin

Sorry here I m again with questions:

  1. I am not able to access id even inside flatMap.
  2. Just to test if I am putting empty string in place of id again compiler is complaining below error:
  3. How will I get document in filter function?

Thanks in advance…


#7

Hi, here’s how the code I previously posted looks like with JDK 1.6:

    final List<String> idsNotFound = new  ArrayList<String>();
    Observable.from(ids).flatMap(new Func1<String, Observable<? extends JsonDocument>>() {

        @Override
        public Observable<? extends JsonDocument> call(String id) {
            return dsBucket.async().get(id).switchIfEmpty(dsBucket.async().get(doSomethingwithId(id)))
                    .defaultIfEmpty(null).filter(new Func1<JsonDocument, Boolean>() {
                @Override
                public Boolean call(JsonDocument doc) {
                    if (doc == null) {
                        idsNotFound.add(id);
                        return false;
                    } else {
                        return true;
                    }
                }
            });
        }
    }).toList().toBlocking().single();

#8

Thanks @ldoguin, It worked this time.