aggregate
功能:(sideEffect)在遍歷過程中,將輸入objects聚合成一個list<object>,并保存在sideEffect。
備注:
單步不會影響輸入objects,下一個單步仍然以objects作為輸入。
單步生成的list<object>是只讀的,在后續遍歷的任意位置可以通過
cap()
取值。PS:不推薦通過
select()
取值。由于select()
對每個實體都會返回一個list<object>,多個實體就會返回多個一樣的list<object>。
單步可以被
by()
修飾,用于指定聚合的字段值。單步會隱式地插入
barrier()
,使用store()
可以不阻塞地實現lazy聚合。aggregate()
、as()
、fold()
的差異?aggregate()
是將輸入聚合為list并拷貝到sideEffect,下一個單步以objects作為輸入,拷貝值對后續遍歷來說是只讀的。as()
是對輸入打標,下一個單步以帶標的objects作為輸入,帶標的objects對后續遍歷來說是可修改的。fold()
是將輸入聚合為list,下一個單步以list作為輸入。
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").aggregate("x").by("name")
==> {"label":"person","age":29,"name":"marko","pk":"1"}
==> {"label":"person","age":32,"name":"josh","pk":"4"}
==> {"label":"person","age":27,"name":"vadas","pk":"2"}
==> {"label":"person","age":35,"name":"peter","pk":"6"}
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").aggregate("x").by("name").cap("x")
==> ["josh","marko","peter","vadas"]
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").aggregate("x").by("name").filter("age>=32").cap("x")
==> ["josh","marko","peter","vadas"]
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").aggregate("x").by("name").outE("knows").aggregate("y").cap("x","y").dedup()
==> {"\"x\"":["josh","marko","peter","vadas"],"\"y\"":[{"label":"knows","pk":"1","sk":"2","weight":0.5},{"label":"knows","pk":"1","sk":"4","weight":1.0}]}
alias
功能:(sideEffect)為輸入實體(點或邊)定義虛擬字段。
格式:
alias("expr1:new1;expr2;new2;field1:new3")
備注:
單步支持將定義為表達式虛擬字段。
單步支持為原始字段定義虛擬字段,相當于為原始字段定義了別名。
重點:為原始字段定義別名后,后續遍歷只能通過別名訪問該字段。
不允許存在重復的字段名。
此單步為iGraph自研擴展的單步
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").alias("name:nick;age*2:double_age")
==> {"label":"person","age":29,"double_age":58,"nick":"marko","pk":"1"}
==> {"label":"person","age":32,"double_age":64,"nick":"josh","pk":"4"}
==> {"label":"person","age":27,"double_age":54,"nick":"vadas","pk":"2"}
==> {"label":"person","age":35,"double_age":70,"nick":"peter","pk":"6"}
// 定義別名后,用老名字訪問字段將返回空結果
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").alias("name:nick").values("name")
==> []
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").alias("name:nick").values("nick")
==> ["marko","josh","vadas","peter"]
and
功能:(filter)返回“所有子遍歷都產生結果”的輸入。
備注:單步可以傳入不定長個數的遍歷。
// 找到年齡在[32,35)之間的人
g("thinkerpop").V("1;2;4;6").hasLabel("person").and(has("age",P.lt(35)),has("age",P.gte(32)))
==> {"label":"person","age":32,"name":"josh","pk":"4"}
// 找到年齡在大于28歲,并且朋友不少于2個的人
g("thinkerpop").V("1;2;4;6").hasLabel("person").and(has("age",P.gt(28)),outE("knows")).count().is(P.gte(2)))
==> {"label":"person","age":29,"name":"marko","pk":"1"}
as
功能:(修飾符)為輸入objects打標,從而讓后續單步和數據結構訪問到。
備注:
單步可以為一批結果打多個標簽。
單步生成帶標objects,下一個單步以帶標的objects作為輸入,在后續遍歷的任意位置可以通過
select()
取值。select()
獲取多個標簽值時會得到map<label,objects>
。select()
可被by()
修飾,指定返回標簽的某個字段。
aggregate()
、as()
、fold()
的差異?aggregate()
是將輸入聚合為list并拷貝到sideEffect,下一個單步以objects作為輸入,拷貝值對后續遍歷來說是只讀的。as()
是對輸入打標,下一個單步以帶標的objects作為輸入,帶標的objects對后續遍歷來說是可修改的。fold()
是將輸入聚合為list,下一個單步以list作為輸入。
結果集中的
"label":"person"
用于展示實體對應的圖label,和as()
的打標值不是一個含義。
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").as("x").select("x")
==> {"label":"person","age":29,"name":"marko","pk":"1"}
==> {"label":"person","age":32,"name":"josh","pk":"4"}
==> {"label":"person","age":27,"name":"vadas","pk":"2"}
==> {"label":"person","age":35,"name":"peter","pk":"6"}
// filter單步以帶標的objects作為輸入,并且過濾了某些objects
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person")as("x").filter("age>=32").select("x")
==> {"label":"person","age":32,"name":"josh","pk":"4"}
==> {"label":"person","age":35,"name":"peter","pk":"6"}
// 單步可通過as()被多個標簽關聯
// select()獲取多個標簽值時會得到map<label,objects>
// select()被by()修飾,指定獲取label的哪個字段
g("thinkerpop").V("1;2").hasLabel("person").as("x","y","z").select("x","y","z").by("pk").by("name").by("age")
==> {"\"x\"":"1","\"y\"":"marko","\"z\"":29}
==> {"\"x\"":"2","\"y\"":"vadas","\"z\"":27}
barrier
功能:(map)阻塞。
barrier()
前的所有單步都執行完后,才開始執行barrier()
后的單步。備注:
單步默認合并相同的objects。
合并方法:將實體的bulk值相加,實體的sack值按規則合并。
目的:如果輸入有十個bulk=1的頂點A,
進行
barrier().outE()
。barrier()
返回一個bulk=10的頂點A。outE()
需要計算一次,得到一個bulk=10的結果。進行
outE()
,需要計算十次,得到十個相同的bulk=1的結果。
用戶一般感受不到合并操作的存在。因為返回最終結果時,bulk>1的實體會按照bulk值成倍地被展開,展開時不會修改bulk值。
通過
bulk()
可以獲取實體的bulk值通過
local(count())
可以計算單個object的數量,即獲取相同object的數量
barrier(Barrier.nodedup)
只阻塞,不合并相同objects。aggregate()
、cap()
、count()
、dedup()
、distinct()
、fold()
、group()
、groupCount()
、limit()
、max()
、mean()
、min()
、order()
、range()
、sample()
、sum()
、tail()
等單步會隱式插入barrier()
// barrier將相同的objects合并為一個object,并且bulk值被設置為重復的數量
// 一般情況下,用戶感受不到合并操作的存在,因為在輸出結果前,objects會按照bulk值展開
g("thinkerpop").E("1;2;3;4;5;6").hasLabel("created").inV().barrier()
==> {"label":"software","lang":"java","name":"lop","pk":"3"}
==> {"label":"software","lang":"java","name":"lop","pk":"3"}
==> {"label":"software","lang":"java","name":"lop","pk":"3"}
==> {"label":"software","lang":"java","name":"ripple","pk":"5"}
// 通過bulk()獲取實體的bulk值
// 返回結果前展開,一個bulk=3的軟件3變成三個bulk=3的軟件3
g("thinkerpop").E("1;2;3;4;5;6").hasLabel("created").inV().barrier().bulk()
// 通過local(count())計算單個object的數量,即獲取相同object的數量
g("thinkerpop").E("1;2;3;4;5;6").hasLabel("created").inV().barrier().local(count())
==> [3,1]
// barrier(Barrier.nodedup) 只阻塞,不會合并相同objects。
g("thinkerpop").E("1;2;3;4;5;6").hasLabel("created").inV().barrier(Barrier.nodedup)
==> {"label":"software","lang":"java","name":"lop","pk":"3"}
==> {"label":"software","lang":"java","name":"lop","pk":"3"}
==> {"label":"software","lang":"java","name":"lop","pk":"3"}
==> {"label":"software","lang":"java","name":"ripple","pk":"5"}
// 不合并時,實體的bulk值都為1
g("thinkerpop").E("1;2;3;4;5;6").hasLabel("created").inV().barrier(Barrier.nodedup).bulk()
==> [1,1,1,1]
branch
功能:(branch)分支查詢。
備注:
需要和
option()
聯合使用。子遍歷的計算結果滿足第一個條件,則進入第一個分支;否則,繼續比較第二個條件。
單步可以傳入不定長個數的遍歷。
和
choose()
功能類似
// if (name=marko) {輸出age}
// else {輸出name}
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").branch(values("name")).option("marko",values("age")).option(none,values("name"))
==> [29,"josh","vadas","peter"]
bulk
功能:(map)返回實體的bulk值
備注:
實體的bulk值初始為1。
barrier()
合并相同結果時,bulk值會相加。用戶一般感受不到合并操作的存在。因為返回最終結果時,bulk>1的實體會按照bulk值成倍地被展開,展開時不會修改bulk值。
dedup()重置bulk值為1。
g("thinkerpop").E("1;2;3;4;5;6").hasLabel("created").inV()
==> {"label":"software","lang":"java","name":"lop","pk":"3"}
==> {"label":"software","lang":"java","name":"lop","pk":"3"}
==> {"label":"software","lang":"java","name":"lop","pk":"3"}
==> {"label":"software","lang":"java","name":"ripple","pk":"5"}
// barrier()合并三個bulk=1的軟件3為一個bulk=3的軟件3
// 返回結果前展開,一個bulk=3的軟件3變成三個bulk=3的軟件3
g("thinkerpop").E("1;2;3;4;5;6").hasLabel("created").inV().barrier().bulk()
==> 3
==> 3
==> 3
==> 1
// barrier()合并三個bulk=1的軟件3為一個bulk=3的軟件3
// dedup()重置一個bulk=3的軟件3為一個bulk=1的軟件3
// 返回結果前展開,四個頂點變成了二個
g("thinkerpop").E("1;2;3;4;5;6").hasLabel("created").inV().barrier().dedup().bulk()
==> 1
==> 1
by
功能:(修飾符)為其他單步提供遍歷、函數、比較器等參數。最通用的形式是
step().by()...by()
。備注:下面的這些單步操作都支持
by()
。每個語義詳見單步的章節aggregate()
:通過by()
指定聚合的字段值。cyclicPath()
:通過by()
指定有環路徑上需要記錄的字段dedup()
:通過by()
指定去重時需要比較的字段值distinct()
:通過by()
指定打散規則group()
:通過by()
指定分組規則和組內存放的值groupCount()
:通過by()
指定分組的規則order()
:通過by()
指定排序規則以及升序/降序/亂序path()
:通過by()
指定路徑上需要記錄的字段project()
:通過by()
指定映射的value值sample()
:通過by()
指定某個字段的值作為采樣權重,權重越高采樣到的概率越大select()
:通過by()
指定獲取標簽的某個字段simplePath()
:按照by()
來過濾保留簡單路徑(非循環路徑即成為簡單路徑)
cap
功能:(map)返回sideEffect的存儲值
備注:
單步支持讀取sideEffect的多個存儲值,會得到
map<key,sideEffect>
。單步會隱式地插入
barrier()
g("thinkerpop").E("1;2;3;4;5;6").hasLabel("created").inV().groupCount("x").by("name").cap("x")
==> {"lop":3,"ripple":1}
// 讀取sideEffect的多個存儲值,會得到map<key,sideEffect>
g("thinkerpop").E("1;2;3;4;5;6").hasLabel("created").groupCount("x").by("pk").groupCount("y").by("weight").cap("x","y")
==> {"\"x\"":{"\"1\"":1,"\"4\"":2,"\"6\"":1},"\"y\"":{"0.2":1,"0.4":2,"1.0":1}}
choose
功能:(branch)分支查詢。
備注:
子遍歷的計算結果滿足第一個條件,則進入第一個分支;否則,繼續比較第二個條件。
單步可以傳入不定長個數的遍歷。
與
branch()
功能類似
// if (name=marko) {輸出age}
// else {輸出name}
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").choose(has("name","marko"),values("age"), values("name"))
==> 29
==> "josh"
==> "vadas"
==> "peter"
// if (age<=30) {輸出朋友關系}
// else {輸出創造關系)
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").choose(values("age").is(P.lte(30)),__.outE("knows"),__.outE("created"))
==> {"label":"knows","pk":"1","sk":"4","weight":1.0}
==> {"label":"knows","pk":"1","sk":"2","weight":0.5}
==> {"label":"created","pk":"4","sk":"3","weight":0.4}
==> {"label":"created","pk":"4","sk":"5","weight":1.0}
==> {"label":"created","pk":"6","sk":"3","weight":0.2}
// if (age=29) {輸出朋友關系}
// else if (age=27) {輸出創造關系}
// else {輸出自己}
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").choose(values("age")).option(29,__.outE("knows")).option(32,__.outE("created")).option(none,identity())
==> {"label":"knows","pk":"1","sk":"4","weight":1.0}
==> {"label":"knows","pk":"1","sk":"2","weight":0.5}
==> {"label":"created","pk":"4","sk":"3","weight":0.4}
==> {"label":"created","pk":"4","sk":"5","weight":1.0}
==> {"label":"person","age":35,"nick":"peter","pk":"6"}
coalesce
功能:(branch)按順序處理輸入,返回首個“至少能計算出一個元素”的輸入的計算值
備注:單步可以傳入不定長個數的遍歷。
// 先計算出朋友關系,故輸出朋友關系
g("thinkerpop").V("1").hasLabel("person").coalesce(outE("knows")outE("created"))
==> {"label":"knows","pk":"1","sk":"4","weight":1.0}
==> {"label":"knows","pk":"1","sk":"2","weight":0.5}
// 先計算出創造關系,故輸出創造關系
g("thinkerpop").V("1").hasLabel("person").coalesce(outE("created"),outE("knows"))
==> {"label":"created","pk":"1","sk":"3","weight":0.4}
constant
功能:(map)返回用戶自定義的“值”。
備注:
單步僅支持數值或者string。
單步常見于分支查詢。
// if (age<=30) {輸出“young man”}
// else {輸出年齡)
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").choose(filter("age<30"),constant("young man"),values("age"))
==> "young man"
==> "32"
==> "young man"
==> "35"
// if (有年齡) {輸出年齡}
// else {輸出5}
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").union(outE("knows").inV(),outE("created").inV()).coalesce(properties("age"), constant(5))
==> {"age":32}
==> {"age":27}
==> 5
==> 5
==> 5
==> 5
count
功能:(map)計算輸入objects的數量
備注:
count(Scope.local)
支持對迭代器類型(list、set等)的輸入求容器內元素個數單步會隱式地插入
barrier()
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").count()
==> 4
// 對fold()生成的list<object>,求容器內的元素個數
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").fold().count(Scope.local)
==> 4
cyclicPath
功能:(filter)返回有環的路徑
備注:
單步可以被
by()
修飾,用于指定有環路徑上需要記錄的字段simplePath()
返回無環的路徑
g("thinkerpop").V("1").hasLabel("person").out().out().cyclicPath().path()
==> 空結果(說明圖thinkerpop不包含有向環)
dedup
功能:(filter)對輸入進行去重。
備注:
如果遍歷的bulk大于1,單步會將bulk重設成1
單步可以被
by()
修飾,用于指定去重時需要比較的字段值。字段值相同的objects,會隨機保留一個。
單步支持對
as()
標簽進行去重單步會隱式地插入
barrier()
g("thinkerpop").E("1;2;3;4;5;6").hasLabel("created").inV()
==> {"label":"software","lang":"java","name":"lop","pk":"3"}
==> {"label":"software","lang":"java","name":"lop","pk":"3"}
==> {"label":"software","lang":"java","name":"lop","pk":"3"}
==> {"label":"software","lang":"java","name":"ripple","pk":"5"}
g("thinkerpop").E("1;2;3;4;5;6").hasLabel("created").inV().dedup()
==> {"label":"software","lang":"java","name":"lop","pk":"3"}
==> {"label":"software","lang":"java","name":"ripple","pk":"5"}
// 隨機保留一個lang字段相同的objects
g("thinkerpop").E("1;2;3;4;5;6").hasLabel("created").inV().dedup().by("lang")
==> {"label":"software","lang":"java","name":"lop","pk":"3"}
// 按照x和y標簽的值,進行去重。
g("thinkerpop").E("1;2;3;4;5;6").hasLabel("created").as("x").inV().as("y").dedup("x","y")
==> {"label":"software","lang":"java","name":"lop","pk":"3"}
==> {"label":"software","lang":"java","name":"lop","pk":"3"}
==> {"label":"software","lang":"java","name":"lop","pk":"3"}
==> {"label":"software","lang":"java","name":"ripple","pk":"5"}
distinct
功能:(filter)打散。按照某種規則對結果進行hash,并從每個hash桶抽取固定數量的結果。
備注
單步支持
Distinct.round
指定抽取輪數,默認抽取1輪單步支持
Distinct.amount
指定每個桶每輪抽取的個數,默認每個桶每輪抽取1個
單步支持
Distinct.isReserved
指定附加未抽取到結果集末尾,默認丟棄剩余結果單步可以被
by()
修飾,用于指定打散規則單步會隱式地插入
barrier()
此單步為iGraph自研擴展的單步
// 按照pk分桶,默認抽取1輪,默認每個桶每輪抽取1個,默認丟棄未被抽取的結果
g("thinkerpop").E("1;2;3;4;5;6").hasLabel("created").distinct().by("pk")
==> {"label":"created","pk":"6","sk":"3","weight":0.2}
==> {"label":"created","pk":"1","sk":"3","weight":0.4}
==> {"label":"created","pk":"4","sk":"3","weight":0.4}
// 按照“pk”分桶,指定抽取2輪,指定每個桶每輪抽取1個,默認丟棄未被抽取的結果
g("thinkerpop").E("1;2;3;4;5;6").hasLabel("created").distinct(Distinct.round,2,Distinct.amount,1).by("pk")
==> {"label":"created","pk":"6","sk":"3","weight":0.2}
==> {"label":"created","pk":"1","sk":"3","weight":0.4}
==> {"label":"created","pk":"4","sk":"3","weight":0.4}
==> {"label":"created","pk":"4","sk":"5","weight":1.0}
// 按照“朋友的個數”分桶,默認抽取1輪,默認每個桶每輪抽取1個,指定附加未被抽取的結果到結果集的末尾
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").distinct(Distinct.isReserved).by(__.outE("created").count())
==> {"label":"person","age":27,"name":"vadas","pk":"2"}
==> {"label":"person","age":32,"name":"josh","pk":"4"}
==> {"label":"person","age":29,"name":"marko","pk":"1"}
==> {"label":"person","age":35,"name":"peter","pk":"6"}
E
功能:(實體)查詢邊的信息。
語法:不同的pkey字符串用
;
分割;pkey指定多個skey的格式為pk:sk1|sk2|...
備注:
圖訪問方式:通過
hasLabel()
指定要訪問的邊對應的圖label
g("thinkerpop").E("1:3;4:3|5;6").hasLabel("created")
==> {"label":"created","pk":"1","sk":"3","weight":0.4}
==> {"label":"created","pk":"4","sk":"3","weight":0.4}
==> {"label":"created","pk":"4","sk":"5","weight":1.0}
==> {"label":"created","pk":"6","sk":"3","weight":0.2}
emit
功能:(修飾符)記錄循環的中間結果。
備注:需要與
loop()
、repeat()
等結合使用。
fields
功能:(sideEffect)裁剪實體(點/邊)的字段
格式:不同的字段名用
;
隔開備注:
pkey和skey字段不可被裁剪
單步有利于減少數據的傳輸量
此單步為iGraph自研擴展的單步
g("thinkerpop").E("1:3;4:3|5;6").hasLabel("created").fields("pk;sk")
==> {"label":"created","pk":"1","sk":"3"}
==> {"label":"created","pk":"4","sk":"3"}
==> {"label":"created","pk":"4","sk":"5"}
==> {"label":"created","pk":"6","sk":"3"}
filter
功能:(filter)過濾實體。滿足過濾條件的實體被保留;否則,被丟棄。
備注:單步支持表達式或者子遍歷作為過濾條件
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").filter("age<30")
==> {"label":"person","age":29,"name":"marko","pk":"1"}
==> {"label":"person","age":27,"name":"vadas","pk":"2"}
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").filter(__.outE("knows"))
==> {"label":"person","age":29,"name":"marko","pk":"1"}
fold
功能:(map)將輸入objects聚合成list<object>
備注:
aggregate()
、as()
、fold()
的差異?aggregate()
是將輸入聚合為list并拷貝到sideEffect,下一個單步以objects作為輸入,拷貝值對后續遍歷來說是只讀的。as()
是對輸入打標,下一個單步以帶標的objects作為輸入,帶標的objects對后續遍歷來說是可修改的。fold()
是將輸入聚合為list,下一個單步以list作為輸入。
unfold()
是相反的操作,可展開list單步會隱式地插入
barrier()
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").values("name").fold()
==> ["marko","josh","vadas","peter"]
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").values("name").fold().unfold()
==> "marko"
==> "josh"
==> "vadas"
==> "peter"
group
功能:(map)將輸入objects按照規則進行分組
備注:
單步可以被兩個
by()
修飾先通過
by()
指定分組的規則,再通過by()
指定每組存放的值分組規則【必選填】,可以是表達式或者子遍歷
存放的值【可選項】,可以是表達式或者子遍歷的值,默認是objects本身。
單步會隱式地插入
barrier()
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").group().by(outE("knows".count())
==> {"0":[{"label":"person","age":32,"name":"josh","pk":"4"},{"label":"person","age":27,"name":"vadas","pk":"2"},{"label":"person","age":35,"name":"peter","pk":"6"}],"2":[{"label":"person","age":29,"name":"marko","pk":"1"}]}
// 按照label進行分組,每組保留結果中的name字段值
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").union(outE("knows").inV(),outE("created").inV()).group().by(T.label).by("name")
==> {"\"person\"":["josh","vadas"],"\"software\"":["lop","lop","ripple","lop"]}
常見用法
// 按照f1分組后,組內再按照weight降序排序,每組保留前2個結果
......group().by("f1").select(Column.values).unfold().flatMap(__.unfold().order().by("weight", decr).limit(2))
groupCount
功能:(sideEffect)將輸入objects按照規則進行分組,并輸出每組包含的objects個數
備注:
單步可以被
by()
修飾,用于指定分組的規則分組規則【可選項】,可以是表達式或者子遍歷
單步支持將分組的結果拷貝到sideEffect,后續遍歷再通過
cap()
取值。單步會隱式地插入
barrier()
g("thinkerpop").E("1;2;3;4;5;6").hasLabel("created").groupCount().by("pk")
==> {"\"1\"":1,"\"4\"":2,"\"6\"":1}
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").union(outE("knows").inV().outE("created").inV()).groupCount().by(T.label)
==> {"\"person\"":2,"\"software\"":4}
// 將分組的結果拷貝到sideEffect,后續遍歷再通過cap()取值
g("thinkerpop").E("1;2;3;4;5;6").hasLabel("created").groupCount("x").by("pk").groupCount("y").by("weight").cap("x","y")
==> {"\"x\"":{"\"1\"":1,"\"4\"":2,"\"6\"":1},"\"y\"":{"0.2":1,"0.4":2,"1.0":1}}