Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
158 views
in Technique[技术] by (71.8m points)

java - Spring-data-aerospike 'findByAttribute' operation working mysteriously

Link followed :- https://www.aerospike.com/blog/spring-data-for-aerospike/

We have an below sample Entity :-

@Document(collection = "cust", expiration = 90, expirationUnit = TimeUnit.DAYS)
public class Customer {

   @Id
   @Field(value = "PK")
   private String custId;

   @Field(value = "mobileNumber")
   private String mobileNumber;

   @Field(value = "creationTime")
   private String creationTime;
 
@Field(value = "custType")
private String custType;
 
}

Using the Spring-repository, We are using below method :-

// WORKS List<Customer> findByMobileNumber (String mobileNumber);

// FAILS with 201 ERR INNDEX NOT FOUND. List<Customer> findByMobileNumberAndCustType (String mobileNumber, String customerType);

Facts / Observations :-

1.) We have not created any explicit secondary indices on our aerospike-set.

2.) When we query(select * from test.cust where mobileNumber = ‘981XXXXXXX’) for the same record using AQL,it fails giving us an error of Indices not found.

Concerns / Questions :-

a.) How does the first one method is working ? What’s the internal way of it being executed ? Are there any on the fly, secondary indices getting created and getting washed away as soon as query is done ?

b.) Why the second one fails ?

Any response shall be highly appreciated !!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

in order to use spring-data findBy** methods, you should have index for queried fields (in your case, index for bin mobileNumber), otherwise, aerospike will need full scan of all documents in your collection (whether full scan be proceeded or rejected - depends on aerospike configuration). index will not be automatically created. so please create index (either programmatically or manually). in case programmatically, you could use the following method:

public void createIndex(AerospikeRepository<?, ?> aerospikeRepository,
                        Class<?> entityClass,
                        String indexName,
                        String fieldName,
                        IndexType indexType) {
    var entityName = entityClass.getSimpleName();
    log.info("Creating Aerospike index [{}] for field [{}] of entity [{}]", indexName, fieldName, entityName);
    try {
        aerospikeRepository.createIndex(entityClass, indexName, fieldName, indexType);
        log.info("Aerospike index [{}] was successfully created for field [{}] of entity [{}]", indexName, fieldName, entityName);
    } catch (IndexAlreadyExistsException ex) {
        log.info("Aerospike index [{}] for field [{}] of entity [{}] already exists", indexName, fieldName, entityName);
    } catch (AerospikeException e) {
        if (e.getResultCode() == ResultCode.INDEX_ALREADY_EXISTS) {
            log.info("Aerospike index [{}] for field [{}] of entity [{}] already exists", indexName, fieldName, entityName);
            return;
        }
        throw e;
    }
}

you could invoke this method createIndex in spring-boot app either in InitializingBean afterPropertiesSet() or in @PostConstruct:

createIndex(customerRepository, Customer.class, "customer_mobileNumber_index", "mobileNumber", IndexType.STRING);

still, such index will fetch records only by a single field mobileNumber, and you need to filter out returned result in java code by customerType


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...