繁体   English   中英

Gremlin 中的决策树查询

[英]Decision Tree query in Gremlin

我已经简化了一个决策图。 它以开始顶点开始,以决策结束。 我的目标是在行驶不同的路径(到达决策顶点)时计算得分总和(与顶点相关的得分)。

Graph 的输入是 json。

顶点之间的边包含可以从输入 json 检查的变量和值。

示例输入 json:{ "age":45,"income_source":"job" }

输出是分数的总和 [10 + 15 + 22] = 47

neo4j cypher 查询允许将 json 输入作为查询参数传递,但我不知道如何在 gremlin 中完成。

图链接: https://gremlify.com/nwgxqs5h7zh/

g.addV('begin').as('beg').
addV('decision').property('score',0).property('decision_code',"minor").as('dec0').

addV('age').property('score',10).as('age10').
addV('age').property('score',20).as('age20').

addV('salary').property('score',15).as('sal15').
addV('salary').property('score',25).as('sal25').

addV('salary').property('score',18).as('sal18').
addV('salary').property('score',30).as('sal30').

addV('decision').property('score',22).property('decision_code',"decision_22").as('dec22').
addV('decision').property('score',45).property('decision_code',"decision_45").as('dec45').

addV('decision').property('score',18).property('decision_code',"decision_18").as('dec18').
addV('decision').property('score',30).property('decision_code',"decision_30").as('dec30').


addE('relation').property('var',"age").property('max',18).from('beg').to('dec0').
addE('relation').property('var',"age").property('min',19).property('max',48).from('beg').to('age10').
addE('relation').property('var',"age").property('min',49).property('max',80).from('beg').to('age20').


addE('relation').property('var',"income_source").property('val',"job").from('age10').to('sal15').
addE('relation').property('var',"income_source").property('val',"buisness").from('age10').to('sal25').

addE('relation').property('var',"income_source").property('val',"job").from('age20').to('sal18').
addE('relation').property('var',"income_source").property('val',"buisness").from('age20').to('sal30').

addE('relation').from('sal15').to('dec22').
addE('relation').from('sal25').to('dec45').
addE('relation').from('sal18').to('dec18').
addE('relation').from('sal30').to('dec30')  

请让我知道这个问题是否可以用不同的方式建模以获得相同的 output 分数

感谢您的时间。

我已将输入 JSON 转换为列表。 此列表中元素的顺序很重要。 它决定遍历将比较列表中哪个元素的级别。

 g.withSack(0).
  inject(["age", 45, "income_source", "job"]).as("input").

# initialized sack and input List

  V().hasLabel("begin").
  outE().as('a').local(and(
          select("input").unfold().range(0, 1).as("temp").
              select("a").values("var").where(eq("temp")), # FILTER property "var"

          select("input").unfold().range(1, 2).as("temp").
              select("a").values("max").where(gte("temp")).
              select("a").values("min").where(lte("temp")))). # FILTER by age from input.

  inV().sack(sum).by("score").
  outE().as("b").local(and(
      select("input").unfold().range(2, 3).as("temp").
          select("b").values("var").where(eq("temp")), # FILTER property "var"

      select("input").unfold().range(3, 4).as("temp").
          select("b").values("val").where(eq("temp")))). # FILTER property val 

  inV().sack(sum).by("score").
  out().sack(sum).by("score").
  sack()
             

您可以将 map inject到 Gremlin 查询中,该查询与您的 JSON 文档的形状基本相同。 查询第一部分的基本构建块看起来像这样,我使用您的数据和 TinkerGraph 对其进行了测试。

gremlin> g.inject(['age':45,'source':'job']).as('data').
......1>   V().hasLabel('begin').
......2>   outE().as('e1').
......3>   where(gte('e1')).
......4>     by(select('data').select('age')).
......5>     by('min').
......6>   where(lte('e1')).
......7>     by(select('data').select('age')).
......8>     by('max').
......9>   valueMap()  

==>[min:19,max:48,var:age] 

下一步是找到具有job标签的边。

gremlin> g.inject(['age':45,'source':'job']).as('data').
......1>   V().hasLabel('begin').
......2>   outE().as('e1').
......3>   where(gte('e1')).
......4>     by(select('data').select('age')).
......5>     by('min').
......6>   where(lte('e1')).
......7>     by(select('data').select('age')).
......8>     by('max').
......9>   inV().
.....10>   outE().as('e2').
.....11>   where(eq('e2')).
.....12>     by(select('data').select('source')).
.....13>     by('val').valueMap()

==>[val:job,var:income_source]     

我们现在需要做的就是遍历最终节点并计算总和。

gremlin> g.withSack(0).
......1>   inject(['age':45,'source':'job']).as('data').
......2>   V().hasLabel('begin').
......3>   outE().as('e1').
......4>   where(gte('e1')).
......5>     by(select('data').select('age')).
......6>     by('min').
......7>   where(lte('e1')).
......8>     by(select('data').select('age')).
......9>     by('max').
.....10>   inV().
.....11>   sack(sum).
.....12>     by('score').
.....13>   outE().as('e2').
.....14>   where(eq('e2')).
.....15>     by(select('data').select('source')).
.....16>     by('val').
.....17>   inV().
.....18>   sack(sum).
.....19>     by('score').
.....20>   out().
.....21>   sack(sum).
.....22>     by('score').
.....23>   sack() 

==>47 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM