2016-08-09 41 views
1

我想通过使用异步获取来提高查询couchbase视图的性能。 我看过他们的文档有关正确的方式做的话,它会是这样的:如何从使用批量的couchbase获得有序的结果获取

Cluster cluster = CouchbaseCluster.create(); 
Bucket bucket = cluster.openBucket(); 


List<JsonDocument> foundDocs = Observable 
.just("key1", "key2", "key3", "key4", "key5") 
.flatMap(new Func1<String, Observable<JsonDocument>>() { 
    @Override 
    public Observable<JsonDocument> call(String id) { 
     return bucket.async().get(id); 
    } 
}) 
.toList() 
.toBlocking() 
.single(); 

伟大的工程和快速,但因为我靠结果的顺序上,看来我需要做的一些额外的工作,以保持结果的顺序。 在上面的示例中,JsonDocument列表包含所有5个文档,但顺序随呼叫而变化。 使用JavaRx功能或者couchbase Java SDK功能来排序结果有没有优雅的方法?

我能想到的唯一解决方案是将结果保存到HashMap中,然后使用此HashMap将原始ID列表转换为JsonDocuments的有序列表。

回答

2

相反的flatMap,你可以使用:

  • concatMap:会保留命令,但实际上等待每个内部的GET来完成在发射下一个之前(可以恢复为具有较少性能的顺序执行)
  • concatMapEager:将立即订阅内部Observable(因此触发内部GET)。通过缓冲顺序到达的响应来维持顺序,直到顺序中正确的索引重播为止。在订购和性能方面,两者都是最好的。
+0

是否有任何理由选择concatMap over concatMapEager?内部GET执行顺序无关紧要,但返回列表的顺序应与输入列表匹配。 – Eyal

+0

ConcatMap没有缓冲区,如果例如所有的响应都是相反的顺序,并且你做了大量的获取,那么缓冲区可能会变得非常大。那会是内存开销。除此之外,不是真的AFAIK –

0

我会用邮编运营商Concat的所有观测,然后一旦他们完成添加文档结果到列表

@Test 
public void zipObservables() { 
    Observable<String> oKey1 = Observable.just("key1").doOnNext(getDocument()); 
    Observable<String> oKey2 = Observable.just("key2").doOnNext(getDocument()); 
    Observable<String> oKey3 = Observable.just("key3").doOnNext(getDocument()); 
    Observable<String> oKey4 = Observable.just("key4").doOnNext(getDocument()); 

    List<Observable<String>> observables = Arrays.asList(oKey1,oKey2,oKey3,oKey4); 
    List<Object> foundDocs = Observable.zip(observables, Arrays::asList) 
      .toBlocking() 
      .single(); 
} 

private Action1<String> getDocument() { 
    return id -> bucket.async().get(id); 
} 

你可以在这里看到更多的邮编例子https://github.com/politrons/reactive/blob/master/src/test/java/rx/observables/combining/ObservableZip.java

+0

它可能会工作,但按键给出的输入列表,所以按键的数量可能会改变,所以对于我的具体问题是行不通 – Eyal

+0

你可以通过一个集合邮编运营商,所以你要善于用那。检查我的示例中的更新 – paul

+0

但是,它指的是4个键。你可以更改方法是zipObservables(列表键),并仍然返回结果,如你所建议的? – Eyal