我正在对couchbase文档进行部分更新,如下所示:
...
MutateInBuilder builder = bucket.mutateIn(id);
for (Map.Entry<String, Object> entry : map.entrySet())
{
builder = builder.upsert(entry.getKey(), entry.getValue());
}
builder.execute();
...
当所有upsert调用中的所有值都属于同一类型时,一切正常。
但是,如果某些值是字符串,并且其他值是布尔值,则我们得到例外:
com.couchbase.client.core.CouchbaseException:SUBDOC_INVALID_COMBO 在com.couchbase.client.java.subdoc.SubdocHelper.commonSubdocErrors(SubdocHelper.java:100) 在com.couchbase.client.java.subdoc.AsyncMutateInBuilder $ 2.call(AsyncMutateInBuilder.java:1094) 在com.couchbase.client.java.subdoc.AsyncMutateInBuilder $ 2.call(AsyncMutateInBuilder.java:1052)
在upsert的测试用例中,找不到任何更新多个属性的情况。
我们如何在Couchbase中使用不同类型的属性备份文档?
编辑#1:
现在,事情变得更奇怪......如果我在一次迭代中更新超过16个属性,我会得到相同的异常。
答案 0 :(得分:1)
从Couchbase Sub-Document API documentation(参见限制部分):
您不能在lookup-in或mutate-in命令中组合超过16个操作。
我猜你在两种情况下遇到了这种限制,混合值类型和单值类型。
使用Couchbase Java SDK 2.3.7版验证。
答案 1 :(得分:0)
现在,我们按类对属性进行分组,并执行与类型一样多的文档upsert。
for(Map.Entry<Class, Map<String, Object>> entry : attributesByClass.entrySet())
{
MutateInBuilder builder = bucket.mutateIn(id);
for (Map.Entry<String, Object> tmp : entry.getValue().entrySet())
{
builder = builder.upsert(tmp.getKey(), tmp.getValue());
}
builder.execute();
}
这是一个效率低下的黑客。欢迎提供更好的解决方案。
答案 2 :(得分:0)
您可以一次合并16个操作中的多个操作,然后执行mutateInBuilder。这将减少操作次数。
MutateInBuilder mutateInBuilder = bucket.mutateIn(id);
int valueCount = 1;
for (Map.Entry<String, JsonElement> entry : valueEntries) {
mutateInBuilder.upsert(entry.getKey(), entry.getValue().getAsString());
if(valueCount % 16 == 0){ // Limitation of subdoc operations for jdk 2.7
mutateInBuilder.execute();
mutateInBuilder = bucket.mutateIn(id);
}
valueCount++;
}
mutateInBuilder.execute();