OrientDB技术问询:筛选符合全部指定日期条件的Claim顶点
Hey there! 既然你熟悉SQL但刚接触OrientDB,我来帮你搞定这个查询问题~
你的核心需求是找到Claim类的顶点,满足两个关键条件:
- 该顶点至少有一条
available_to_role类型的出边,且边的role属性值为'adj1' - 这些边连接的入顶点,必须包含所有你指定的
date值(不是满足其中一个就行)
之前的查询问题在于,它按入顶点的date分组,只能拿到单个日期对应的结果,没法判断某个Claim是否覆盖了全部指定日期。下面给你两种可行的解决方案:
方案1:用OrientDB的MATCH语句(推荐,更适合图查询场景)
MATCH是OrientDB专门针对图遍历设计的查询语法,写起来更直观,性能也更优:
MATCH {class: Claim, as: claim} .outE('available_to_role'){role: 'adj1'} .inV(){date IN ['2018-06-02 00:00:00','2018-06-03 00:00:00'], as: dateVertex} GROUP BY claim HAVING COUNT(DISTINCT dateVertex.date) = SIZE(['2018-06-02 00:00:00','2018-06-03 00:00:00']) RETURN claim.*, claim.label as claim_label
逻辑解释:
- 先遍历所有Claim顶点,标记为
claim - 接着沿着
available_to_role出边过滤,只保留role='adj1'的边 - 再找到这些边连接的入顶点,过滤出
date在指定列表里的,标记为dateVertex - 按
claim分组,统计每个Claim对应的不同date数量,只有当数量等于指定日期的总数时(用SIZE()函数自动计算列表长度,不用手动改数字),才返回该Claim的信息
方案2:SQL风格嵌套查询(适合习惯SQL的你)
如果你更倾向于用熟悉的SQL写法,可以用嵌套子查询来实现:
SELECT *, label as claim_label FROM Claim WHERE ( SELECT COUNT(DISTINCT date) FROM ( SELECT in.date FROM available_to_role WHERE out = $parent.$current AND role = 'adj1' AND in.date IN ['2018-06-02 00:00:00','2018-06-03 00:00:00'] ) ) = SIZE(['2018-06-02 00:00:00','2018-06-03 00:00:00'])
逻辑解释:
- 外层查询遍历所有Claim顶点
- 内层子查询统计当前Claim(
$parent.$current指代外层的当前Claim)通过符合条件的边连接到的不同date的数量 - 只有当这个数量等于指定日期的总数时,才保留该Claim
小提示:
- 如果你的日期列表是动态生成的,用
SIZE()函数可以自动匹配数量,不用手动修改数字,非常方便 - 建议优先尝试MATCH写法,OrientDB对图遍历的优化在MATCH上做得更好,复杂场景下性能会比SQL风格查询高很多
内容的提问来源于stack exchange,提问作者Lance
相关产品推荐
相关产品推荐

