I have a hazelcast Ilist,The student class contains 5 properties like(id,name,address,number,school).Now there are 10k records in the list,how can I find the student whose name is tony and number is 001 quickly except for for loop.I hnow if it is a Imap I can use predicate to filter ,but it is a list ,I didn't find a predicate for Ilist.Any help ,thanks a lot.
find an entry in hazelcast list quickly
1.4k Views Asked by Jeffrey AtThere are 2 best solutions below
On
I can not get what id in the object is for as you need to query id+name (therefore id is not intended to be unique?). Why you store them in a Set if you know you will need to query them (please give more info).
As you pointed out there are not predicates in Set. IMHO this is because entries not associated with a Key can not be indexed. Without possibility to ad an index (Or at leas range-scan on key) the concept of predicates crumble down, as any query will still iterate over the entire set. As far as i can see, you do not have many options:
If you are using set must to have unique entries, don't!
In this case, move it to a map, an use a key as anyone, for example your object id. If there may be id, duplicates, you can make more complex key like id+name or even hash the entire object. Once you have to put a new Object make the key and check if it is already present if so fallback with your custom logic. Map will give you all the Indexes and predicates you can wish for.
From the other hand if for some reasons that are not under your control you Must use set... then you can do it in many ways but I will suggest as follow:
Listen on any modification to the Set (Or if is static or consistency is not a concern scan periodically the set
Build your custom index
How to build the index:
It really depend upon the performances you want, the RAM impact you can accept and how different queries may be. (Let assume that you only queries are always the same eg "name equals to").
MultiMap<String, String> index
// index.put(name, key)
You structure your index by adding, removing entries on each Set modification, using in your MultiMap the object.name as key and actual Key in the Set as value in the multimap. Once you search for a give name you simply do as follow (pseudo-pseudo code)
MultiMap<String, String> index;
Map<String, your_object_class> your_set;
function getByName(String name)
{
List<String> name_key_set index.get( name );
List<your_object_class> out;
for(String key : name_key_set)
out.add(index.get(key));
return out;
}
IMO there is nothing you can call query on a Set ( referring to query as a clever way to retrieve data and not a brute force iteration ) as any such system will require key=>value entries.
With further information we can help you better :)
Unfortunately there is no way to do this with some kind of a predicate or other magic. You have to do a loop. To speed it up, however, you should run this search on the member that contains the list. Partitioning is defined by the name of the list though. You can basically write yourself a small "query engine" to utilize the Hazelcast predicates on top of a list.
I created a basic example, you can most probably optimize it though.
A simple student class:
The search executor:
And finally how to run this code:
I hope this helps a bit :)