基本框架
- hugegraph 提供queryCondition對(duì)象,用戶可以指定節(jié)點(diǎn)屬性,屬性的條件蝗砾,比如 name=‘A’ AND age >10
- 存儲(chǔ)引擎負(fù)責(zé)將一個(gè) queryConditon對(duì)象翻譯成具體 的查詢語(yǔ)句,比如sql
- 根據(jù)query的meta data 處理 分頁(yè), 排序等問(wèn)題。
學(xué)習(xí)他的建模思想
對(duì)于同一個(gè)功能,不同水平的程序員寫出來(lái)的代碼是完全不一樣的。
在以往的編碼中,我寫嘗試過(guò)使用面向?qū)ο蟮恼Z(yǔ)言,完成模糊條件建模南誊。
當(dāng)時(shí)我的需求是這樣的橄务,我給客戶提供一個(gè) 靈活的 api迫肖, api里面有 n個(gè)屬性玻粪。
用戶可以指定屬性的查詢條件, 我的實(shí)現(xiàn)很簡(jiǎn)單很簡(jiǎn)單
public class PropertyCondition
{
private String property;
private CompareOp.CompareType comparator;
private Object value;
public PropertyCondition copy()
{
return new PropertyCondition(this.property, this.comparator, this.value);
}
}
存在的問(wèn)題是:
- 沒有對(duì)query的建模结窘,一個(gè)query 通常是 對(duì)condtion的集合很洋,還有metadata,比如分頁(yè)隧枫,排序
- 在需要多個(gè)condition時(shí)候喉磁,只能是用list來(lái)hold,且無(wú)法做 and or 等邏輯關(guān)系官脓。
- 無(wú)法方便的創(chuàng)建和復(fù)用對(duì)象协怒,比如 我創(chuàng)建一個(gè) new PropertyCondition("age",LGT, 10), 這樣的語(yǔ)句將充斥者整個(gè)代碼庫(kù),更好的方法是復(fù)用 靜態(tài)方法而不是新建對(duì)象卑笨。
學(xué)習(xí) huge graph的模型
看完hugegraph的模型孕暇,我以后再實(shí)現(xiàn)condition 的時(shí)候可能會(huì)借鑒很多他的想法。
類關(guān)系如下:
- QUery對(duì)象赤兴,為基類妖滔, 包含 對(duì)一個(gè)查詢的描述。
- IDQUery 繼承 query桶良,描述對(duì)于指定ID查詢
- ConditionQuery, 繼承query座舍,描述基于條件的查詢, 包含了一個(gè) Set<Condition>
- Condition對(duì)象是對(duì)于各種模糊條件的抽象艺普,下面仔細(xì)講解簸州。
- 還有一個(gè)flattenCondition對(duì)象,主要是對(duì) In歧譬,NotIn 這樣的條件進(jìn)行 flatten岸浑,配合者 Condition對(duì)象使用。
來(lái)看看Condition對(duì)象是如何實(shí)現(xiàn)的瑰步。
首先是對(duì)關(guān)系類型的建模:
public enum RelationType implements BiPredicate<Object, Object> {
EQ("==", (v1, v2) -> {return equals(v1, v2); }),
GT(">", (v1, v2) -> { return compare(v1, v2) > 0; }),
GTE(">=", (v1, v2) -> { return compare(v1, v2) >= 0; }),
LT("<", (v1, v2) -> { return compare(v1, v2) < 0; }),
LTE("<=", (v1, v2) -> { return compare(v1, v2) <= 0; }),
NEQ("!=", (v1, v2) -> { return compare(v1, v2) != 0; }),
IN("in", (v1, v2) -> {
return ((Collection<?>) v2).contains(v1);
}),
NOT_IN("notin", (v1, v2) -> {
return !((Collection<?>) v2).contains(v1);
}),
利用了java 的函數(shù)功能矢洲,每個(gè)運(yùn)算符是一個(gè)可以 自我test的對(duì)象,
比如EQ.test("A","B"), 一看這代碼就寫的特別專業(yè)缩焦,運(yùn)用lambada表達(dá)是也恰到好處读虏。
另外责静,內(nèi)置了大量的靜態(tài)方法 生成想要的condition對(duì)象。
public static Relation eq(Id key, Object value) {
return new UserpropRelation(key, RelationType.EQ, value);
}
public static Relation gt(Id key, Object value) {
return new UserpropRelation(key, RelationType.GT, value);
}
public static Relation gte(Id key, Object value) {
return new UserpropRelation(key, RelationType.GTE, value);
}
public static Relation lt(Id key, Object value) {
return new UserpropRelation(key, RelationType.LT, value);
}
public static Relation lte(Id key, Object value) {
return new UserpropRelation(key, RelationType.LTE, value);
}
public static Relation neq(Id key, Object value) {
return new UserpropRelation(key, RelationType.NEQ, value);
}
在使用condition時(shí)候盖桥,使用 Condition.lt("name","3") 灾螃,可讀性強(qiáng)。
同理對(duì)于queryCondition揩徊,也內(nèi)置了靜態(tài)方法腰鬼,非常方便的加入多個(gè)condition到query語(yǔ)句中。
public ConditionQuery gt(HugeKeys key, Object value) {
return this.query(Condition.gt(key, value));
}
public ConditionQuery gte(HugeKeys key, Object value) {
return this.query(Condition.gte(key, value));
}
public ConditionQuery lt(HugeKeys key, Object value) {
return this.query(Condition.lt(key, value));
}
public ConditionQuery lte(HugeKeys key, Object value) {
return this.query(Condition.lte(key, value));
}
本小節(jié)就講到這里了塑荒,代碼的細(xì)節(jié)熄赡,顯示出一個(gè)人編程能力。