@Document
annotated classed are generic entities for saving any data into the storage, so it does not use data type specific operations.
In case you want to work directly with lists you should be using raw aerospike client API for now. Here is an example how this can be done in Java:
https://github.com/aerospike/aerospike-client-java/blob/master/examples/src/com/aerospike/examples/OperateList.java#L53
There is another solution using spring-data-aerospike
, but it won't be such effective as working directly with list append operation as you will need to firstly retrieve data, modify it and then save.
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);
}
}
I've added @Version
field and @Retryable
so that in case you have multiple concurrently running updates on server you won't loose some of the updates. This algorithm is known as CAS (you can read more information about this here: What is CAS in NoSQL and how to use it? )