如何使用批量获取来自couchbase的有序结果

时间:2016-08-09 10:55:20

标签: couchbase rx-java couchbase-view

我正在尝试通过使用async gets来提高查询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 个答案:

答案 0 :(得分:2)

您可以使用:

代替flatMap
  • concatMap:将保留顺序,但实际上等待每个内部GET完成后再触发下一个(可以恢复顺序执行,性能较差)
  • concatMapEager:将立即订阅内部Observable(因此触发内部GET)。通过缓冲无序到达的响应来维持顺序,直到它们可以在序列中的正确索引处重放。在订购和性能方面,两全其美。

答案 1 :(得分:0)

我会使用Zip运算符来连接所有可观察对象,然后一旦完成将文档结果添加到列表中

   @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);
}

您可以在此处查看更多Zip示例https://github.com/politrons/reactive/blob/master/src/test/java/rx/observables/combining/ObservableZip.java