一個高性能的java 集合搜索工具。使用它,可以用類似sql的語句對Java集合進行檢索,且延遲極低。
作者對其優(yōu)點的描述是:每秒百萬次的查詢,查詢延遲在微秒范圍內(nèi),轉(zhuǎn)移數(shù)據(jù)庫的查詢帶寬,擴展應用層,是數(shù)據(jù)庫查詢速度的千倍,即使在低端硬件上。關(guān)于cqengin和傳統(tǒng)java 集合查詢的性能比較dzone.com: Comparing the search performance of CQEngine with standard Java collections。相關(guān)概念1索引cqengin 通過在對象的字段上創(chuàng)建索引解決擴展性和延遲問題。在一個對象集合中,簡單索引可以被添加到任意數(shù)量的單個字段上,使得基于這些屬性的查詢都是O(1)的時間復雜度對一個對象字段,可以添加多個索引,每個索引對應不同的查詢,例如,字段相等,字段值在某個范圍內(nèi),字符串字段以某個串開始等復合索引針對多個字段cqengin同時支持嵌套索引,類似于sql語句:"WHERE color = 'blue' AND(NOT(doors = 2 OR PRice > 53.00))"2屬性cqengin需要訪問對象字段以便建立索引,并檢索這些字段的值,它不是通過反射,而是采用 attributes來實現(xiàn)這一目的。attribute是一個更強大的概念,它是可以讀取pojo某個字段值的對象訪問器。如下語句對一個Car對象定義attribute。它能夠訪問car對象的carId.
public static final Attribute<Car, Integer> Car_ID = attribute("carId", Car::getCarId);
第一個參數(shù)是可選的,但是官方文檔里推薦這種作法。另外,在Car類里定義上述attribute 是通常的作法,但這并不是強制,跟一個類相關(guān)的attribute可以定義在任何一個地方。多值attribute,訪問對象的集合字段,如下圖,features是一個list<String>類型字段
public static final Attribute<Car, String> FEATURES = attribute(String.class, "features", Car::getFeatures);
給定一個對象,attribute被要求返回一個值,多數(shù)情況下,這個值是一個對象的字段值,同時,還可以是應用于其他字段或外部數(shù)據(jù)的函數(shù)的返回值。如: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方法獲取結(jié)果值,
以下是一個完整的示例:
@Servicepublic class searchService { public static final Attribute<Car, Integer> Car_ID = attribute("carId", Car::getCarId); public static final Attribute<Car, String> DESCRIPTION = attribute("carDesc", Car::getDescription); public static final MultiValueAttribute<Car, String> FEATURES = attribute(String.class, "features", Car::getFeatures); //使用query public String test1() { StringBuffer sbBuffer=new StringBuffer(); IndexedCollection<Car> cars = new ConcurrentIndexedCollection<Car>(); //添加對象 cars.add(new Car(1, "ford focus", "great condition, low mileage", Arrays.asList("spare tyre", "sunroof"))); cars.add(new Car(2, "ford taurus", "dirty and unreliable, flat tyre", Arrays.asList("spare tyre", "radio"))); cars.add(new Car(3, "honda civic", "has a flat tyre and high mileage", Arrays.asList("radio"))); //添加索引 cars.addIndex(NavigableIndex.onAttribute(Car_ID)); cars.addIndex(SuffixTreeIndex.onAttribute(DESCRIPTION)); cars.addIndex(HashIndex.onAttribute(FEATURES)); //創(chuàng)建查詢 Query<Car> query1 = and(startsWith(DESCRIPTION, "great"), lessThan(Car_ID, 4)); //獲取查詢結(jié)果 ResultSet<Car> result=cars.retrieve(query1); if(result.isNotEmpty()){ result.forEach(e->{ sbBuffer.append(e.toString()); sbBuffer.append("/n"); }); return sbBuffer.toString(); }else{ return "nothing found"; } }啟動類:
@SpringBootapplication@RestControllerpublic class DemoApplication { @Autowired private searchService ss; public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @RequestMapping("/") public String hello(){ return ss.test1(); } }運行后訪問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
新聞熱點
疑難解答