Thursday, April 21, 2011

ehcache search example

Search was released in ehcache recently and has been getting quite a traction from various users. This small blog is to explain how you can use search in your application with an example application.

1. What is Search
When the search is enabled then while building the cache an index of element is built according to what has been provided as searchable attribute by the user. This knowledge can later be used to execute complex queries in the cache. This cache be standalone ehcache or Terracotta clustered cache. For example a query like this can be executed

2. What can you Search
The search is to get the results out of the Elements of the cache based on keys or values. The criteria upon which search can be done is provided by the user at the time of initialization of cache against which indexing would be done.

3. Enabling Search
Enabling search is fairly easy. All you need to do is to add searchable tag in cache definition section of the ehcache.xml file. Here is an example.

<cache name="cache2" maxElementsInMemory="10000" eternal="true" overflowToDisk="false">
<searchable/>
</cache>

This the simplest way to enable search. This will simply see all the keys and values and check whether they are searchable type and if the are then will add them as search attributes. This will by default start automatic indexing. To disable it you can do this

<cache name="cache3" ...>
<searchable keys="false" values="false">
...
</searchable>
</cache>

When keys or values are not directly searchable then we need to extract searchable attributes out. In that case you can provide the method name which should return a searchable type and can be used for indexing. A typical example is
<cache name="cache3" maxElementsInMemory="10000" eternal="true" overflowToDisk="false">
<searchable>
<searchAttribute name="age" class="net.sf.ehcache.search.TestAttributeExtractor"/>
<searchAttribute name="gender" expression="value.getGender()"/>
</searchable>
</cache>

You can also do this programatically like this

SearchAttribute sa = new SearchAttribute();
sa.setExpression("value.getAge()"); sa.setName("age"); cacheConfig.addSearchAttribute(sa);
4. Search Attribute
The user has to define search attribute either in config file or programatically to enable the indexing and query in the cache. Search attributes are a way to tell the cache what is need to be indexed so that it can be queried later on. Here is how you define a search attribute in the cache

5. Querying the Cache
If the rest of steps you have followed correctly then you are pretty much done and ready to do complex queries from your cache. All you need to do is to crate a query, add specific criteria, add aggregators if you wish to, and execute. Here is an example.

Query query = cache.createQuery().addCriteria(age.eq(35)).includeKeys().end(); Results results = query.execute();
Now you have the result of your specific query. You can do these operations on your result set to server your purpose.

discard() :Discard this query result. This call is not mandatory but is recommended after the caller is done with results. It can allow the cache, which may be distributed, to immediately free any resources associated with this result.


List all() : Retrieve all of the cache results in one shot


List range(int start, int count) : Retrieve a subset of the cache results


int size(): returns size of the result set


boolean hasKeys() : Whether the Results have cache keys included


boolean hasValues() : Whether the Results have cache values included.


boolean hasAttributes() : Whether the Results have cache attributes included.


boolean hasAggregators() : Whether the results contains aggregates



More documentation can be found here

1 comment:

Anonymous said...

Hi, Raghu!
thank you for your post.
I am getting used to ehcache api now, and i've been puzzled with one issue.
When putting in cache simple key and some object as a value, it is OK to find that object afterwards.
But if i use some compound key (say, consisting of ten fields, overriding hash and equals for that compound key of course) - i fail o find my element in cahe via the cache.createQuery().includeKeys().addCriteria(someCriteria).execute().all(). Please, tell me if there are any pitfalls in the usage of compond keys in the ehcache