JAVA集合缓存查询引擎CQengine使用范例

1个高性能的 Java 集合搜索工具。使用它,可以用类似sql的语句对Java集合进行检索,且延迟极低。


作者对其优点的描述是:每秒百万次的查询,查询延迟在微秒范围内,转移数据库的查询带宽,扩展应用层,是数据库查询速度的千倍,即使在低端硬件上。

关于cqengin和传统java 集合查询的性能比较dzone.com: Comparing the search performance of CQEngine with standard Java collections。

相关概念
1索引
cqengin 通过在对象的字段上创建索引解决扩展性和延迟问题。
在一个对象集合中,简单索引可以被添加到任意数量的单个字段上,使得基于这些属性的查询都是O(1)的时间复杂度
对一个对象字段,可以添加多个索引,每个索引对应不同的查询,例如,字段相等,字段值在某个范围内,字符串字段以某个串开始等
复合索引针对多个字段
cqengin同时支持嵌套索引,类似于sql语句:"WHERE color = 'blue' AND(NOT(doors = 2 OR price > 53.00))"

2属性
cqengin需要访问对象字段以便建立索引,并检索这些字段的值,它不是通过反射,而是采用 attributes來实现这一目的。
attribute是一个更强大的概念,它是可以读取pojo某个字段值的对象访问器。
如下语句对一个Car对象定义attribute。它能够访问car对象的carId.


public static final Attribute<Car, Integer> Car_ID = attribute("carId", Car::getCarId);


第一个参数是可选的,但是官方文档里推荐这种作法。另外,在Car类里定义上述attribute 是通常的作法,但这并不是强制,跟一个类相关的attribute可以定义在任何一个地方。
多值attribute,访问对象的集合字段,如下图,features是一个list<String>类型字段

public static final Attribute<Car, String> FEATURES = attribute(String.class, "features", Car::getFeatures);


给定一个对象,attribute被要求返回一个值,多数情况下,这个值是一个对象的字段值,同时,还可以是应用于其他字段或外部数据的函数的返回值。如:
public static final Attribute<Car, Boolean> IS_DIRTY = attribute("dirty", car -> car.description.contains("dirty"));

如下attribute能够访问每个car的serviceLocation。
public static final Attribute<Car, String> SERVICE_LOCATIONS = new MultiValueAttribute<Car, String>() {
    public List<String> getValues(Car car, QueryOptions queryOptions) {
        return CarServiceManager.getServiceLocationsForCar(car);
    }
};


3.query

CQengine使用query来检索对象。同时可以使用sql语句或者CQN(cqengine native)

通过retrieve方法获取结果值,

以下是一个完整的示例:

  1. @Service  
  2. public class searchService {  
  3.       
  4.     public static final Attribute<Car, Integer> Car_ID = attribute("carId", Car::getCarId);  
  5.     public static final Attribute<Car, String> DESCRIPTION = attribute("carDesc", Car::getDescription);  
  6.     public static final MultiValueAttribute<Car, String> FEATURES = attribute(String.class"features", Car::getFeatures);  
  7.       
  8.     //使用query  
  9.     public String test1()  
  10.     {  
  11.         StringBuffer sbBuffer=new StringBuffer();  
  12.         IndexedCollection<Car> cars = new ConcurrentIndexedCollection<Car>();  
  13.         //添加对象  
  14.         cars.add(new Car(1"ford focus""great condition, low mileage", Arrays.asList("spare tyre""sunroof")));  
  15.         cars.add(new Car(2"ford taurus""dirty and unreliable, flat tyre", Arrays.asList("spare tyre""radio")));  
  16.         cars.add(new Car(3"honda civic""has a flat tyre and high mileage", Arrays.asList("radio")));  
  17.         //添加索引  
  18.           
  19.         cars.addIndex(NavigableIndex.onAttribute(Car_ID));  
  20.         cars.addIndex(SuffixTreeIndex.onAttribute(DESCRIPTION));  
  21.         cars.addIndex(HashIndex.onAttribute(FEATURES));  
  22.           
  23.         //创建查询  
  24.          Query<Car> query1 = and(startsWith(DESCRIPTION, "great"), lessThan(Car_ID, 4));  
  25.          //获取查询结果  
  26.          ResultSet<Car> result=cars.retrieve(query1);  
  27.          if(result.isNotEmpty()){  
  28.              result.forEach(e->{  
  29.                  sbBuffer.append(e.toString());  
  30.                   sbBuffer.append("\n");  
  31.              });  
  32.              return sbBuffer.toString();  
  33.          }else{  
  34.              return "nothing found";  
  35.          }  
  36.             
  37.             
  38.     }  


启动类:

  1. @SpringBootApplication  
  2. @RestController  
  3. public class DemoApplication {  
  4.       
  5.     @Autowired  
  6.     private searchService ss;  
  7.   
  8.     public static void main(String[] args) {  
  9.         SpringApplication.run(DemoApplication.class, args);  
  10.     }  
  11.       
  12.   
  13.     @RequestMapping("/")  
  14.     public String hello(){  
  15.         return ss.test1();  
  16.     }  
  17.       
  18. }  

运行后访问8080端口,输出: 找出了id小于4,且描述以greate开头的car.

参考:

http://stackoverflow.com/questions/37766895/can-cqengine-query-an-object-inside-another-object

https://github.com/npgall/cqengine

https://dzone.com/articles/getting-started-cqengine-linq
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值