基本框架
- hugegraph 提供queryCondition对象,用户可以指定节点属性,属性的条件,比如 name=‘A’ AND age >10
- 存储引擎负责将一个 queryConditon对象翻译成具体 的查询语句,比如sql
- 根据query的meta data 处理 分页, 排序等问题。
学习他的建模思想
对于同一个功能,不同水平的程序员写出来的代码是完全不一样的。
在以往的编码中,我写尝试过使用面向对象的语言,完成模糊条件建模。
当时我的需求是这样的,我给客户提供一个 灵活的 api, api里面有 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);
}
}
存在的问题是:
- 没有对query的建模,一个query 通常是 对condtion的集合,还有metadata,比如分页,排序
- 在需要多个condition时候,只能是用list来hold,且无法做 and or 等逻辑关系。
- 无法方便的创建和复用对象,比如 我创建一个 new PropertyCondition("age",LGT, 10), 这样的语句将充斥者整个代码库,更好的方法是复用 静态方法而不是新建对象。
学习 huge graph的模型
看完hugegraph的模型,我以后再实现condition 的时候可能会借鉴很多他的想法。
类关系如下:
- QUery对象,为基类, 包含 对一个查询的描述。
- IDQUery 继承 query,描述对于指定ID查询
- ConditionQuery, 继承query,描述基于条件的查询, 包含了一个 Set<Condition>
- Condition对象是对于各种模糊条件的抽象,下面仔细讲解。
- 还有一个flattenCondition对象,主要是对 In,NotIn 这样的条件进行 flatten,配合者 Condition对象使用。
来看看Condition对象是如何实现的。
首先是对关系类型的建模:
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 的函数功能,每个运算符是一个可以 自我test的对象,
比如EQ.test("A","B"), 一看这代码就写的特别专业,运用lambada表达是也恰到好处。
另外,内置了大量的静态方法 生成想要的condition对象。
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时候,使用 Condition.lt("name","3") ,可读性强。
同理对于queryCondition,也内置了静态方法,非常方便的加入多个condition到query语句中。
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));
}
本小节就讲到这里了,代码的细节,显示出一个人编程能力。
网友评论