如何使用批量获取从 couchbase 获取有序结果

How to get ordered results from couchbase using bulk 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 列表。

我会使用 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

代替flatMap,您可以使用:

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