0

对于给定id的我的主键,如果已经存在,我想将数据附加到 List 类型id,如果不存在,那么我想创建新的 List。

这是我的 aerospike 模式 -

Column1: columnname=id; columntype=Integer; columnconstraint=primarykey
Column2: columnname=mylist; columntype=List<String>

下面是我的 POJO :

public class AeroSpikeModel {

    @Id
    private Integer id;

    private List<String> myList = new ArrayList<>();

   //getter and setter
}

这是我的 DAO:

@Component
public class MyDAO {

    @Autowired
    private AerospikeRepository<AeroSpikeModel, Integer> aerospikeRepository;

    public void save(List<AeroSpikeModel> model) {
        aerospikeRepository.save(model);
     }

    public AeroSpikeModel get(Integer id) {
        return aerospikeRepository.findOne(id);
    }

}

问题是每次我插入现有id列表时,它都会覆盖列表而不是附加到现有列表中。我如何实现相同的目标,因为 aerospike 本身支持附加到列表

4

1 回答 1

0

@Document带注释的类是用于将任何数据保存到存储中的通用实体,因此它不使用特定于数据类型的操作。

如果您想直接使用列表,您现在应该使用原始 aerospike 客户端 API。这是如何在 Java 中完成此操作的示例: https ://github.com/aerospike/aerospike-client-java/blob/master/examples/src/com/aerospike/examples/OperateList.java#L53

还有另一种使用 的解决方案spring-data-aerospike,但它不会像直接使用列表附加操作那样有效,因为您需要首先检索数据,修改它然后保存。

import lombok.Builder;
import lombok.Data;
import org.springframework.data.aerospike.mapping.Document;

    @Document
    @Data
    @Builder(toBuilder=true)
    public static class MyDocument {
        @Id
        public final long id;
        public final Set<String> items;
        public final String someString;
// Stores document version in this field. 
// In Aerospike terms it is referred to as generation. 
// Without this field CAS (compare-and-set) algorithm won't take place in spring-data
        @Version
        public long version;

    public static class MyDocumentBuilder {
        public MyDocumentBuilder addItem(String item) {
            this.items.add(item);
            return this;
        }
    }
}
import org.springframework.data.aerospike.repository.AerospikeRepository;

public interface MyDocumentRepository extends AerospikeRepository<MyDocument, Long> {

}
import lombok.RequiredArgsConstructor;
import org.springframework.dao.OptimisticLockingFailureException;
import org.springframework.retry.annotation.Retryable;

@RequiredArgsConstructor
public class MyDocumentService {

  private final MyDocumentRepository repo;

  // in case version of the document was modified on server -- 
  // we will need to retry our operation from the beginning
  @Retryable(OptimisticLockingFailureException.class)
  public boolean addToCollection(Long id, String itemToAdd) {
    return repo.findById(id)
                .map(found -> updateAndSave(found, itemToAdd))
                .orElse(false);
  }

  private boolean updateAndSave(MyDocument existing, String itemToAdd) {
    MyDocument updated = existing.toBuilder()
            .addItem(itemToAdd)
            .build();
    repo.save(updated);
  }
}

我已经添加了@Version字段,@Retryable这样如果您在服务器上有多个同时运行的更新,您就不会丢失一些更新。该算法被称为 CAS(您可以在此处阅读有关此的更多信息:NoSQL 中的 CAS 是什么以及如何使用它?

于 2019-12-02T17:36:36.293 回答