【问题标题】:Aerospike spring data append to listAerospike 弹簧数据附加到列表
【发布时间】:2019-05-16 21:47:15
【问题描述】:

对于给定的id,这是我的主键,如果id 已经存在,我想将数据附加到 List 类型,否则我想创建新的 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 本身支持追加到列表

【问题讨论】:

    标签: spring-data aerospike aerospike-ce


    【解决方案1】:

    @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(您可以在此处阅读有关此的更多信息:What is CAS in NoSQL and how to use it?)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-24
      • 1970-01-01
      • 1970-01-01
      • 2019-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-04
      相关资源
      最近更新 更多