Searching for the index of specific AAID

Hi Folks, We are trying to fetch the index of data from the list without using the Full Scan on the record we will be having the AAID and we have to fetch the index of only that userId currently it is giving the index in list format i.e. [0,1,2,...] need to get the index of that specific AAID which in our case is 1

Note: Bucket Id is calculated on the basis of first 9 character of the AAID
129709 (BucketId): {
	LIST(
		'70806216-b083-3e19-81d6-4179d891e8f5' (AAID1):{
			MAP(
				1234 (FlightAdId): 1800 (TimeStamp)
				4374 (FlightAdId): 1600 (TimeStamp)
				6876 (FlightAdId): 1600 (TimeStamp)
				inner_ttl: 1800 (Maximum of above three Timestamp)
			)
		},
		'70806216-s793-3d69-90d6-4179d891e8g5' (AAID2):{
			MAP(
				7657 (FlightAdId): 900 (TimeStamp)
				5435 (FlightAdId): 500 (TimeStamp)
				inner_ttl: 900 (Maximum of above two Timestamp)
			)
		},
		'70806216-s793-3d69-70d6-6459d891b4j6' (AAID3):{
			MAP(
				9878 (FlightAdId): 12000 (TimeStamp)
				4454 (FlightAdId): 1000 (TimeStamp)
				inner_ttl: 12000 (Maximum of above two Timestamp)
			)
		}
		...other AAID's
	)
}
Below is the code for achieving the above structure
Note: UserId and AAID are interchangeable term

def write(cls, user_Id, flight_ad_Id, expiration_timestamp, ttl):
        if cls.client is not None:
            try:
                ns = cls.namespace
                bucketId = cls.calculateBucketId(user_Id)
                key = (ns, None, bucketId)
                bin_name = 'bin1'
                index = 0
                ctx = [cdt_ctx.cdt_ctx_map_key(user_Id)]
                ops = [
                    list_operations.list_get_by_value(bin_name, user_Id, aerospike.LIST_RETURN_VALUE, ctx),
                ]
                ops3 = [
                    list_operations.list_get_by_value(bin_name, user_Id, aerospike.LIST_RETURN_INDEX, ctx)
                ]
                a = cls.client.exists(key=key)
                if a[1] is not None:
                    record_exists = cls.client.operate(key, ops)
                    # Check if the key user_Id exists in the list of keys
                    key_exists = any(user_Id in record.keys() for record in record_exists[2][bin_name])
                    record_index = cls.client.operate(key, ops3)
                    index = record_index[2][bin_name][-1] --- **Getting Wrong INDEX VALUE**
                else:
                    record_exists = None
                    key_exists = False

                existing_ttl = 0
                existing_inner_ttl = 0
                inner_ttl_value = datetime.now() + timedelta(seconds=ttl)
                inner_ttl_value = inner_ttl_value.timestamp()
                inner_ttl_to_fetch = 'inner_ttl'

                if key_exists and record_exists is not None and record_exists[2][bin_name] is not None and len(record_exists[2][bin_name]) != 0:
                    for i in record_exists[2][bin_name]:
                        if user_Id in i:
                            existing_data = i  # Access the first element of the list
                            existing_ttl = record_exists[1]['ttl']
                            existing_inner_ttl = existing_data[user_Id][inner_ttl_to_fetch]
                else:
                    existing_data = {}  # Initialize as empty dictionary
                
                if existing_inner_ttl <= inner_ttl_value:
                    inner_ttl_value = inner_ttl_value
                else: 
                    inner_ttl_value = existing_inner_ttl

                # Update or insert flight_ad_Id and expiration_timestamp
                existing_data[user_Id] = {**existing_data.get(user_Id, {}), flight_ad_Id: expiration_timestamp, inner_ttl_to_fetch: int(inner_ttl_value)}

                # Update or insert the list into Aerospike
                if existing_ttl <= ttl:
                    meta = {'ttl': int(ttl)}
                else:
                    meta = {'ttl': int(existing_ttl)}
                
                if key_exists:
                    ops2 = [
                        list_operations.list_set(bin_name=bin_name, index=index, value=existing_data, policy=aerospike.LIST_WRITE_DEFAULT)
                    ]
                else:
                    ops2 = [
                        list_operations.list_append(bin_name=bin_name, value=existing_data, policy=aerospike.LIST_WRITE_DEFAULT)
                    ]
                cls.client.operate(policy=cls.write_policy, key=key, list=ops2, meta=meta)
                
            except Exception as e:
                print(e)
                pass

write(
    user_Id='70806216-s793-3d69-90d6-4179d891e8g5', flight_ad_Id=64099, expiration_timestamp= 1714411696000, ttl=1800
    )

You currently have : A list of key value pairs:

[AAIDx:{}, AAIDy:{} , AAIDz:{}, ...]

You will have to modify it as a List of Lists with the Key being first element of the list. Like so:

[ [AAIDx, AAIDx:{ ...}], [AAIDy, AAIDy:{ ... }], [AAIDz, AAIDz:{....} ] ]

Here is my test output with the above modification to the data structure:

//Add record data
List<Value> aaidlist1 = new ArrayList<Value>();
aaidlist1.add(Value.get("AAID1"));
HashMap <String, Integer> mapAAID1 = new HashMap <String, Integer>();
mapAAID1.put("1234", 1800);
mapAAID1.put("4374", 1600);
mapAAID1.put("6876", 1600);
mapAAID1.put("inner_ttl", 1800);
HashMap <String, HashMap> mapAAID_1 = new HashMap <String, HashMap>();
mapAAID_1.put("AAID1", mapAAID1);
aaidlist1.add(Value.get(mapAAID_1));

List<Value> aaidlist2 = new ArrayList<Value>();
aaidlist2.add(Value.get("AAID2"));
HashMap <String, Integer> mapAAID2 = new HashMap <String, Integer>();
mapAAID2.put("7657", 900);
mapAAID2.put("5435", 500);
mapAAID2.put("inner_ttl", 900);
HashMap <String, HashMap> mapAAID_2 = new HashMap <String, HashMap>();
mapAAID_2.put("AAID2", mapAAID2);
aaidlist2.add(Value.get(mapAAID_2));

List<Value> aaidlist3 = new ArrayList<Value>();
aaidlist3.add(Value.get("AAID3"));
HashMap <String, Integer> mapAAID3 = new HashMap <String, Integer>();
mapAAID3.put("9878", 12000);
mapAAID3.put("4454", 1000);
mapAAID3.put("inner_ttl", 12000);
HashMap <String, HashMap> mapAAID_3 = new HashMap <String, HashMap>();
mapAAID_3.put("AAID3", mapAAID3);
aaidlist3.add(Value.get(mapAAID_3));

client.operate(null, myKey, ListOperation.append(lPolicy, binName, Value.get(aaidlist1)));
client.operate(null, myKey, ListOperation.append(lPolicy, binName, Value.get(aaidlist2)));
client.operate(null, myKey, ListOperation.append(lPolicy, binName, Value.get(aaidlist3)));

System.out.println("My List after mapInsert: "+ client.get(null, myKey));

Output:

My List after mapInsert: 
(gen:3),(exp:452752299),
(bins:(myListBin1:
[
[AAID1, {AAID1={6876=1600, 4374=1600, 1234=1800, inner_ttl=1800}}], 
[AAID2, {AAID2={7657=900, 5435=500, inner_ttl=900}}], 
[AAID3, {AAID3={9878=12000, inner_ttl=12000, 4454=1000}}]
]))

Now you can query using WILDCARD (only applies to List Values):

List<Value> aaidList = new ArrayList<Value>();
aaidList.add(Value.get("AAID2"));
aaidList.add(Value.get(Value.WILDCARD));

System.out.println(client.operate(null, myKey, ListOperation.getByValue("myListBin1", Value.ListValue.get(aaidList), ListReturnType.INDEX)));

System.out.println(client.operate(null, myKey, ListOperation.getByValue("myListBin1", Value.ListValue.get(aaidList), ListReturnType.VALUE)));

and the output is:

(gen:3),(exp:452752299),(bins:(myListBin1:[1]))
(gen:3),(exp:452752299),(bins:(myListBin1:[[AAID2, {AAID2={7657=900, 5435=500, inner_ttl=900}}]]))