Java 异步删除密钥以特定字符串开头的文档

Java 异步删除密钥以特定字符串开头的文档,java,couchbase,Java,Couchbase,我正在尝试从我的bucket中删除所有键以某个字符串开头的文档 我的看法是: private void createAndPublishCacheView() { List<View> views = new ArrayList<View>(); views.add(DefaultView.create("cache_view_by_key", "function (doc, meta) { emit(meta.id, null) }")); DesignDocu

我正在尝试从我的bucket中删除所有键以某个字符串开头的文档

我的看法是:

private void createAndPublishCacheView()
{
 List<View> views = new ArrayList<View>();
 views.add(DefaultView.create("cache_view_by_key", "function (doc, meta) { emit(meta.id, null) }"));

 DesignDocument designDoc   = DesignDocument.create("cache_doc", views);
 this.cacheBucket.bucketManager().upsertDesignDocument(designDoc);
}
然后,控制台上只打印并删除了几个文档,我收到一个:

java.lang.RuntimeException: java.util.concurrent.TimeoutException
at com.couchbase.client.java.util.Blocking.blockForSingle(Blocking.java:75)
at com.couchbase.client.java.CouchbaseBucket.remove(CouchbaseBucket.java:486)
at com.couchbase.client.java.CouchbaseBucket.remove(CouchbaseBucket.java:466)
at com.ventusproxy.tests.couchbase.TestCB$3.onNext(TestCB.java:167)
at com.ventusproxy.tests.couchbase.TestCB$3.onNext(TestCB.java:1)
at rx.observers.SafeSubscriber.onNext(SafeSubscriber.java:130)
如果onNext方法为:

  public void onNext(AsyncViewRow viewRow) 
                { 
                 System.out.println("viewRow.id() = " + viewRow.id());
                 bucket.remove(viewRow.id());
                }
  public void onNext(AsyncViewRow viewRow) 
                { 
                 System.out.println("viewRow.id() = " + viewRow.id());
                 bucket.async().remove(viewRow.id());
                }
然后在控制台上打印所有文档,但不会删除它们

有人能帮我吗

此外,我不确定这是否是删除一大组文档的最有效方法

谢谢


琼。

您试图做的事情有一些问题:

startKeyDocId方法实际上并不像您认为的那样。使用 startKeycallId。 仅指定开始键将返回大于的所有结果 参数,而不仅仅是以该键开始的结果。看法 查询按升序按字典顺序比较键,因此您将得到大于callId的所有字符串。您应该同时指定这两个选项 查询中的开始键和结束键,以及包含的结束键,以正确限制查询。所以cacheView.startKeycallId.endKeycalldId.inclusiveEndtrue从内存中键入时,语法可能会有点不正确。 您正在尝试一次检索所有匹配的密钥。如果有 对于许多结果,查询将超时,因为它需要 太长,无法返回所有结果。如果你期待很多结果,你会说 超过1000个时,您应该使用分页来检索和处理它们 大块。下面是一个关于如何在RxJava中使用可观察对象实现分页的好例子: 异步调用视图查询,但使用阻塞移除调用。您不应该订阅异步查询调用的结果,而应该将其平面映射到bucket.async.removow.id中-然后您可以订阅所有异步删除调用的结果,添加一些重试和错误处理逻辑,等等。看看这里关于实现重试和错误处理的内容:特别是滚动到retryWhen示例。 最后,如果您使用的是Couchbase 4.0,那么可以使用以下N1QL查询来替换整个过程:从bucket中删除METAbucket.id,如“ABC%”;
事实上,我还看到cacheView.startKeyDocIdcallId并没有过滤以“callId”开头的记录,我正在使用onNext方法打印所有记录。附带说明:不需要像在视图中那样将文档的id作为键发出-它们总是发出,并且您实际上正在使用它们。当你得到一个超时时——它总是在同一个文档上吗?超时多长时间?我总是在阅读7或8个文档后收到此超时。我试着在2秒、5秒、10秒的时间内设置好几次超时,但每次都能到达。此外,“cacheView.startKeyDocIdcallId”没有过滤密钥,我不知道为什么。谢谢。嗨,大卫,非常感谢你的回复。是的,我尝试使用N1ql和delete语句,但我没有使用它,因为我认为它在CB4中仍然是实验性的。正如您所说,像delete这样的DML语句在Couchbase 4.0中被认为是beta。但是,像这样简单的方法可以很好地工作,除非您碰巧拥有许多与查询条件匹配的文档。在这种情况下,您还可以通过在DELETE语句中指定要匹配的最大文档数,将其拆分为块。
  public void onNext(AsyncViewRow viewRow) 
                { 
                 System.out.println("viewRow.id() = " + viewRow.id());
                 bucket.async().remove(viewRow.id());
                }