Thursday, July 5, 2012

querying/filtering in-memory data using JFilter

I was looking for a framework which allows to query/filter in memory data. Specific to my case, I was having a list of maps which I wanted to filter. I found JFilter which allows you to filter objects. It works on objects. Below I will be showing how to use JFilter if you have Map as object to filter on.

Before begining I would like to thank Kamran (author of JFilter) for the great framework.

JFilter works on object to make it work on Map you need to wrap your map. For that I have created a Store object with accessor methods for Map.

 import java.util.HashMap;  
 import java.util.Map;  
 public class Store {  
      private Map<String, Object> s = new HashMap<String, Object>();  
      public Map<String, Object> getMap() {  
           return s;  
      }  
      public void setMap(Map<String, Object> s) {  
           this.s = s;  
      }  
      public String toString() {  
           return s.toString();  
      }  
 }  

Now that we have our object ready to query/filter on. We will create a list of Store for our test purpose.

Preparing list of Store

 List<Store> list = new ArrayList<Store>();  
 Map<String, Object> map1 = new HashMap<String, Object>();  
 map1.put("name", "abdullah");  
 map1.put("balance", 700);  
 Store s1 = new Store();  
 s1.setMap(map1);  
 list.add(s1);  
 Map<String, Object> map2 = new HashMap<String, Object>();  
 map2.put("name", "david");  
 map2.put("balance", 850);  
 Store s2 = new Store();  
 s2.setMap(map2);  
 list.add(s2);  
 Map<String, Object> map3 = new HashMap<String, Object>();  
 map3.put("name", "jeffery");  
 map3.put("balance", 400);  
 Store s3 = new Store();  
 s3.setMap(map3);  
 list.add(s3);  

Creating JFilter object and passing it the list of Store to work on.
 JFilter<Store> filter = new JFilter<Store>(list, Store.class);  

Preparing parameters to be passed to JFilter for querying/filtering objects.
 Map<String, Object> parameters = new HashMap<String, Object>();  
 parameters.put("keyName", "name");  
 parameters.put("value", "abdullah");  

To hold the result of querying/filtering we need to pass list, so every time we filter we will pass a list to hold the result.

Equal to
 ArrayList<Store> res1 = new ArrayList<Store>();  
 filter.filter("{'map':{'key':{'$eq':'?keyName'}, 'value':{'$eq':'?value'}}}", parameters).out(res1);  
 System.out.println("= result -> " + res1);  

To hold the filtering result we have res1. We will be callign filter method of JFilter and pass it query, which is in json format and the parameters (you can also use var-args to pass parameters.)

We will be doing the same thing for all the operators below, so I won't be repeating all these details.

Not equals to

 ArrayList<Store> res2 = new ArrayList<Store>();  
 filter.filter("{'map':{'key':{'$eq':'?keyName'}, 'value':{'$ne':'?value'}}}", parameters).out(res2);  
 System.out.println("!= result -> " + res2);  

Preparing parameters for like operations
 parameters.put("keyName", "name");  
 parameters.put("value", "ab");  

Starts with
 ArrayList<Store> res3 = new ArrayList<Store>();  
 filter.filter("{'map':{'key':{'$eq':'?keyName'}, 'value':{'$sw':'?value'}}}", parameters).out(res3);  
 System.out.println("starts with result -> " + res3);  

Ends with
 ArrayList<Store> res4 = new ArrayList<Store>();  
 parameters.put("value", "ry");  
 filter.filter("{'map':{'key':{'$eq':'?keyName'}, 'value':{'$ew':'?value'}}}", parameters).out(res4);  
 System.out.println("ends with result -> " + res4);  

Contains
 ArrayList<Store> res5 = new ArrayList<Store>();  
 parameters.put("value", "vi");  
 filter.filter("{'map':{'key':{'$eq':'?keyName'}, 'value':{'$cts':'?value'}}}", parameters).out(res5);  
 System.out.println("contains result -> " + res5);  

Preparing parameters for in / not in operation
 parameters.put("keyName", "balance");  
 List<Integer> balance = new ArrayList<Integer>();  
 balance.add(300);  
 balance.add(500);  
 balance.add(700);  
 parameters.put("value", balance);  

In
 ArrayList<Store> res6 = new ArrayList<Store>();  
 filter.filter("{'map':{'key':{'$eq':'?keyName'}, 'value':{'$in':'?value'}}}", parameters).out(res6);  
 System.out.println("in result -> " + res6);  

Not In
 ArrayList<Store> res7 = new ArrayList<Store>();  
 filter.filter("{'map':{'key':{'$eq':'?keyName'}, 'value':{'$nin':'?value'}}}", parameters).out(res7);  
 System.out.println("not in result -> " + res7);  

Preparing parameters for relational operators
 parameters.put("keyName", "balance");  
 parameters.put("value", 700);  

Less than
 ArrayList<Store> res8 = new ArrayList<Store>();  
 filter.filter("{'map':{'key':{'$eq':'?keyName'}, 'value':{'$lt':'?value'}}}", parameters).out(res8);  
 System.out.println("< result -> " + res8);  

Less than or equal to
 ArrayList<Store> res9 = new ArrayList<Store>();  
 filter.filter("{'map':{'key':{'$eq':'?keyName'}, 'value':{'$le':'?value'}}}", parameters).out(res9);  
 System.out.println("<= result -> " + res9);  

Greater than
 ArrayList<Store> res10 = new ArrayList<Store>();  
 filter.filter("{'map':{'key':{'$eq':'?keyName'}, 'value':{'$gt':'?value'}}}", parameters).out(res10);  
 System.out.println("> result -> " + res10);  

Greater than or equal to
 ArrayList<Store> res11 = new ArrayList<Store>();  
 filter.filter("{'map':{'key':{'$eq':'?keyName'}, 'value':{'$ge':'?value'}}}", parameters).out(res11);  
 System.out.println(">= result -> " + res11);  

Here is the working code for all operators
 import gk.jfilter.JFilter;  
   
 import java.util.ArrayList;  
 import java.util.HashMap;  
 import java.util.List;  
 import java.util.Map;  
   
 public class Filtering {  
   
      public static void main(String[] args) {  
   
           List<Store> list = new ArrayList<Store>();  
   
           Map<String, Object> map1 = new HashMap<String, Object>();  
           map1.put("name", "abdullah");  
           map1.put("balance", 700);  
   
           Store s1 = new Store();  
           s1.setMap(map1);  
           list.add(s1);  
   
           Map<String, Object> map2 = new HashMap<String, Object>();  
           map2.put("name", "david");  
           map2.put("balance", 850);  
             
           Store s2 = new Store();  
           s2.setMap(map2);  
           list.add(s2);  
   
           Map<String, Object> map3 = new HashMap<String, Object>();  
           map3.put("name", "jeffery");  
           map3.put("balance", 400);  
   
           Store s3 = new Store();  
           s3.setMap(map3);  
           list.add(s3);  
   
           JFilter<Store> filter = new JFilter<Store>(list, Store.class);  
             
           //parameters to be passed for filtering  
           Map<String, Object> parameters = new HashMap<String, Object>();  
           parameters.put("keyName", "name");  
           parameters.put("value", "abdullah");  
             
           //to hold the result after filtering we will be creating list which will be passed to out method.  
   
           //for equal  
           ArrayList<Store> res1 = new ArrayList<Store>();  
           filter.filter("{'map':{'key':{'$eq':'?keyName'}, 'value':{'$eq':'?value'}}}", parameters).out(res1);  
           System.out.println("= result -> " + res1);  
   
           //for not equal  
           ArrayList<Store> res2 = new ArrayList<Store>();  
           filter.filter("{'map':{'key':{'$eq':'?keyName'}, 'value':{'$ne':'?value'}}}", parameters).out(res2);  
           System.out.println("!= result -> " + res2);  
   
           //for like operations  
           parameters.put("keyName", "name");  
           parameters.put("value", "ab");  
             
           //starts with  
           ArrayList<Store> res3 = new ArrayList<Store>();  
           filter.filter("{'map':{'key':{'$eq':'?keyName'}, 'value':{'$sw':'?value'}}}", parameters).out(res3);  
           System.out.println("starts with result -> " + res3);  
             
           //ends with  
           ArrayList<Store> res4 = new ArrayList<Store>();  
           parameters.put("value", "ry");  
           filter.filter("{'map':{'key':{'$eq':'?keyName'}, 'value':{'$ew':'?value'}}}", parameters).out(res4);  
           System.out.println("ends with result -> " + res4);  
   
           //contains  
           ArrayList<Store> res5 = new ArrayList<Store>();  
           parameters.put("value", "vi");  
           filter.filter("{'map':{'key':{'$eq':'?keyName'}, 'value':{'$cts':'?value'}}}", parameters).out(res5);  
           System.out.println("contains result -> " + res5);  
   
           //parameters for in / not in operations  
           parameters.put("keyName", "balance");  
             
           List<Integer> balance = new ArrayList<Integer>();  
           balance.add(300);  
           balance.add(500);  
           balance.add(700);  
           parameters.put("value", balance);  
   
           //for in  
           ArrayList<Store> res6 = new ArrayList<Store>();  
           filter.filter("{'map':{'key':{'$eq':'?keyName'}, 'value':{'$in':'?value'}}}", parameters).out(res6);  
           System.out.println("in result -> " + res6);  
       
           //for not in  
           ArrayList<Store> res7 = new ArrayList<Store>();  
           filter.filter("{'map':{'key':{'$eq':'?keyName'}, 'value':{'$nin':'?value'}}}", parameters).out(res7);  
           System.out.println("not in result -> " + res7);  
   
           //preparing parameters for relational operators   
           parameters.put("keyName", "balance");  
           parameters.put("value", 700);  
             
           //for <  
           ArrayList<Store> res8 = new ArrayList<Store>();  
           filter.filter("{'map':{'key':{'$eq':'?keyName'}, 'value':{'$lt':'?value'}}}", parameters).out(res8);  
           System.out.println("< result -> " + res8);  
             
           //for <=  
           ArrayList<Store> res9 = new ArrayList<Store>();  
           filter.filter("{'map':{'key':{'$eq':'?keyName'}, 'value':{'$le':'?value'}}}", parameters).out(res9);  
           System.out.println("<= result -> " + res9);  
             
           //for >  
           ArrayList<Store> res10 = new ArrayList<Store>();  
           filter.filter("{'map':{'key':{'$eq':'?keyName'}, 'value':{'$gt':'?value'}}}", parameters).out(res10);  
           System.out.println("> result -> " + res10);  
   
           //for >=  
           ArrayList<Store> res11 = new ArrayList<Store>();  
           filter.filter("{'map':{'key':{'$eq':'?keyName'}, 'value':{'$ge':'?value'}}}", parameters).out(res11);  
           System.out.println(">= result -> " + res11);  
   
      }  
 }  
   

2 comments:

  1. Thanks Abdullah for writing this great post about Jfilter.

    ReplyDelete
  2. Jfilter is now moved to https://github.com/khankamranali/jfilter

    ReplyDelete