如何使用Couchbase Java SDK修改bucket中的文档而不更改其;“到期日”;价值

如何使用Couchbase Java SDK修改bucket中的文档而不更改其;“到期日”;价值,java,couchbase,couchbase-java-api,Java,Couchbase,Couchbase Java Api,我必须使用Java SDK修改Couchbase bucket中的一个文档(目前它是版本2.7.7中的一个Java客户端,但是,如果需要,可以更改它),而不更改其“过期”值。bucket中没有索引,N1QL查询不是一个选项,因此我必须坚持使用键/值操作 下面是一个简单的例子,描述了问题所在,以及我迄今为止所做的尝试: 我在bucket中有一个json文档,它是使用Java SDK创建的: JsonObject obj = JsonObject.create() //Setting som

我必须使用Java SDK修改Couchbase bucket中的一个文档(目前它是版本2.7.7中的一个Java客户端,但是,如果需要,可以更改它),而不更改其“过期”值。bucket中没有索引,N1QL查询不是一个选项,因此我必须坚持使用键/值操作

下面是一个简单的例子,描述了问题所在,以及我迄今为止所做的尝试:
我在bucket中有一个json文档,它是使用Java SDK创建的:

JsonObject obj = JsonObject.create()
    //Setting some essential data ... 
    .put(“lessImportant”, “This shouldn’t influence on the expiration time”);
int expiry = ((int)Instant.now().getEpochSecond()) + someOffset;
JsonDocument doc = JsonDocument.create("msg::42", expiry, obj);
bucket.insert(doc);
我想获取这个对象并修改它的“lessImportant”属性,但我不想在执行此操作时更改对象元数据中的“expiration”值

当我尝试设置属性并重新发送对象时:

JsonDocument doc = bucket.get(“msg::42”)
doc.content.put(“otherData”, “I hope expiration remains the same”);
bucket.upsert(doc); 
或在不指定过期值的情况下创建新的过期值:

JsonObject obj = oldDoc.content();
obj.put(“otherData”, “I hope expiration remains the same”);
JsonDocument doc = JsonDocument.create(oldDoc.id(), obj);
bucket.upsert(doc);
或者将upsert()替换为replace(),则我可以看到每次更新文档时,其“过期”值都会被删除(设置为0,这对于Couchbase意味着在插入后,它应该将此文档视为根本没有设置过期日期–文档应该永远保持不变)

正如我所观察到的,每当我创建JsonDocument而没有显式设置“过期”时:

JsonDocument.create(String id, int expiry, JsonObject data);  
默认情况下,此值设置为0:

JsonDocument.create(String id, JsonObject data); //0 is the default`  
此外,无论bucket中的实际过期时间是多少,
bucket.get(String id)
返回的文档总是具有相同的“expiration”属性值,即0(这是SDK的错误还是预期行为?),因此,当我尝试插入检索到的文档时,“expiration”是0:

bucket.upsert(JsonDocument.create(
    “msg::123”, SOME_EXPIRATION, obj));//sets expiration SOME_EXPIRATION
bucket.upsert(bucket.get(“msg::123”));//resets expiration to 0

是否可以以不修改此特定元数据的方式更新文档,或者获取旧的“过期”值,以便在插入之前将其设置为正确的值

您必须在SDK通过扩展AbstractCouchbaseConfiguration读取文档时,在基类中设置过期时间,并在编写此类文档时设置回过期时间,下面给出了一个示例

import com.ishfaqhaider.MyCustomClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
import org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter;
import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
import org.springframework.data.couchbase.repository.config.EnableCouchbaseRepositories;

@Configuration
@EnableCouchbaseRepositories(basePackages = {"com.ishfaqhaider"})
public class CouchbaseConfig extends AbstractCouchbaseConfiguration {

@Bean
@Override
public MappingCouchbaseConverter mappingCouchbaseConverter() throws Exception {
    final MappingCouchbaseConverter converter = new MyCouchbaseConverter(couchbaseMappingContext());
    return converter;
}

static class MyCouchbaseConverter extends MappingCouchbaseConverter {
    @Override
    public <R> R read(final Class<R> clazz, final CouchbaseDocument source) {
        R r= super.read(clazz, source);
        if(clazz==MyCustomClass.class){
        ((MyCustomClass)r).setExpiration(source.getExpiration());
        }
        return r;
    }
    @Override
    public void write(final Object source, final CouchbaseDocument target) {
        if(source instanceof MyCustomClass){
            target.setExpiration(((MyCustomClass)source).getExpiration());
        }
        super.write(source, target);
    }
}
}
import com.ishfaqhaider.MyCustomClass;
导入org.springframework.context.annotation.Bean;
导入org.springframework.context.annotation.Configuration;
导入org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
导入org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter;
导入org.springframework.data.couchbase.core.mapping.couchbase文档;
导入org.springframework.data.couchbase.repository.config.EnableCouchbaseRepositories;
@配置
@EnableCouchbaseRepositories(basePackages={“com.ishfaqhaider”})
公共类CouchbaseConfig扩展了AbstractCouchbaseConfiguration{
@豆子
@凌驾
公共MappingCouchbaseConverter MappingCouchbaseConverter()引发异常{
final MappingCouchbaseConverter converter=新的MyCouchbaseConverter(couchbaseMappingContext());
回流转换器;
}
静态类MyCuchBaseConverter扩展了MappingCouchbaseConverter{
@凌驾
公共R阅读(最终课程分类,最终CouchbaseDocument来源){
R=超级读取(clazz,source);
if(clazz==MyCustomClass.class){
((MyCustomClass)r.setExpiration(source.getExpiration());
}
返回r;
}
@凌驾
公共无效写入(最终对象源、最终CouchbaseDocument目标){
if(MyCustomClass的源实例){
target.setExpiration(((MyCustomClass)source.getExpiration());
}
super.write(源、目标);
}
}
}

您必须在SDK通过扩展AbstractCouchbaseConfiguration来读取文档时,在基类中设置过期时间,并在编写此类文档时设置回过期时间,下面给出了一个示例

import com.ishfaqhaider.MyCustomClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
import org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter;
import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
import org.springframework.data.couchbase.repository.config.EnableCouchbaseRepositories;

@Configuration
@EnableCouchbaseRepositories(basePackages = {"com.ishfaqhaider"})
public class CouchbaseConfig extends AbstractCouchbaseConfiguration {

@Bean
@Override
public MappingCouchbaseConverter mappingCouchbaseConverter() throws Exception {
    final MappingCouchbaseConverter converter = new MyCouchbaseConverter(couchbaseMappingContext());
    return converter;
}

static class MyCouchbaseConverter extends MappingCouchbaseConverter {
    @Override
    public <R> R read(final Class<R> clazz, final CouchbaseDocument source) {
        R r= super.read(clazz, source);
        if(clazz==MyCustomClass.class){
        ((MyCustomClass)r).setExpiration(source.getExpiration());
        }
        return r;
    }
    @Override
    public void write(final Object source, final CouchbaseDocument target) {
        if(source instanceof MyCustomClass){
            target.setExpiration(((MyCustomClass)source).getExpiration());
        }
        super.write(source, target);
    }
}
}
import com.ishfaqhaider.MyCustomClass;
导入org.springframework.context.annotation.Bean;
导入org.springframework.context.annotation.Configuration;
导入org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
导入org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter;
导入org.springframework.data.couchbase.core.mapping.couchbase文档;
导入org.springframework.data.couchbase.repository.config.EnableCouchbaseRepositories;
@配置
@EnableCouchbaseRepositories(basePackages={“com.ishfaqhaider”})
公共类CouchbaseConfig扩展了AbstractCouchbaseConfiguration{
@豆子
@凌驾
公共MappingCouchbaseConverter MappingCouchbaseConverter()引发异常{
final MappingCouchbaseConverter converter=新的MyCouchbaseConverter(couchbaseMappingContext());
回流转换器;
}
静态类MyCuchBaseConverter扩展了MappingCouchbaseConverter{
@凌驾
公共R阅读(最终课程分类,最终CouchbaseDocument来源){
R=超级读取(clazz,source);
if(clazz==MyCustomClass.class){
((MyCustomClass)r.setExpiration(source.getExpiration());
}
返回r;
}
@凌驾
公共无效写入(最终对象源、最终CouchbaseDocument目标){
if(MyCustomClass的源实例){
target.setExpiration(((MyCustomClass)source.getExpiration());
}
super.write(源、目标);
}
}
}

Hello@Ishfaq,这在您的机器上工作吗?我以前没有使用过spring data couchbase,所以可能我遗漏了一些东西,但我已经用spring Boot starter data couchbase创建了全新的spring Boot 2.1.7项目,配置与您的类似,并且我发现myCuchBaseConverter.read()方法中的source.getExpiration()总是返回0(即使是其他严格的字段也是正确的,而且很好)“过期”在Couchbase UI的元数据中可见。也许我应该设置一些额外的配置?我已经在Couchbase Server 6.0 CE的新安装中尝试过了。Hello@Ishfaq,这对您有用吗