option
功能:(修饰符)指定分支查询的条件。
备注:需要与
branch()
结合使用。
optional
功能:(branch)如果子遍历能产生结果,则返回遍历结果;否则,返回输入object。
// 输出朋友关系或者没朋友的可怜人自己的信息
g("thinkerpop").V("1;2;4;6").hasLabel("person").optional(outE("knows"))
==> {"label":"knows","pk":"1","sk":"4","weight":1.0}
==> {"label":"knows","pk":"1","sk":"2","weight":0.5}
==> {"label":"person","age":32,"name":"josh","pk":"4"}
==> {"label":"person","age":27,"name":"vadas","pk":"2"}
==> {"label":"person","age":35,"name":"peter","pk":"6"}
or
功能:(filter)返回“至少在一个子遍历能产生结果”的输入
// 年龄为27或者至少有两个朋友的人
g("thinkerpop").V("1;2;4;6").hasLabel("person").or(outE("knows").count().is(P.gte(2)),filter("age=27"))
==> {"label":"person","age":29,"name":"marko","pk":"1"}
==> {"label":"person","age":27,"name":"vadas","pk":"2"}
order
功能:(map)排序
备注:
单步可以被
by()
修饰,用于指定排序规则以及升序incr
/降序decr
/乱序shuffle
默认按照自身值进行排序,排序规则支持指定字段值和子遍历。
默认为升序
支持通过多个
by()
指定多个排序规则
单步会隐式插入
barrier()
// 按照pk升序,pk相同则按照sk降序
g("thinkerpop").E("1;2;3;4;5;6").hasLabel("created").order().by("pk").by("sk",Order.decr)
==> {"label":"created","pk":"1","sk":"3","weight":0.4}
==> {"label":"created","pk":"4","sk":"5","weight":1.0}
==> {"label":"created","pk":"4","sk":"3","weight":0.4}
==> {"label":"created","pk":"6","sk":"3","weight":0.2}
// 按照人脉数量降序
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").order().by(outE("knows").count(),Order.decr)
==> {"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").values("age").order().by(Order.shuffle)
==> 32
==> 35
==> 29
==> 27
out
功能:(实体)从一个顶点跳转到关联的顶点。
备注:
单步仅支持图访问方式。
通过参数指定要跳转的边在图中对应的label
不指定参数时,默认会访问所有关联的边。
单步会被拆解为
outE().limit(50).inV()
,即出边增加了50的截断。如果不满足需求,请使用outE().limit(300).inV()
模式。出于系统保护的角度,出边不能超过50000。
out().out()
会被优化拆解为outE().limit(50).outE().limit(50).inV()
。用于节约一次顶点的访问。
第一次
ouE()
关联边skey
值,即为第二次outE()
关联边的pkey
值。如果后续遍历中存在
path()
,则此优化不生效。
g("thinkerpop").V("1").hasLabel("person").out("knows")
==> {"label":"person","age":32,"name":"josh","pk":"4"}
==> {"label":"person","age":27,"name":"vadas","pk":"2"}
g("thinkerpop").V("1").hasLabel("person").out()
==> {"label":"software","lang":"java","name":"lop","pk":"3"}
==> {"label":"person","age":32,"name":"josh","pk":"4"}
==> {"label":"person","age":27,"name":"vadas","pk":"2"}
outE
功能:(实体)从一个顶点跳转到关联的边
备注:
图访问方式:通过参数指定要跳转的边在图中对应的label
不指定参数时,默认会访问所有关联的边。
// 默认输入顶点的pkey为跳转字段
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").outE("knows")
==> {"label":"knows","pk":"1","sk":"4","weight":1.0}
==> {"label":"knows","pk":"1","sk":"2","weight":0.5}
g("thinkerpop").V("1").hasLabel("person").outE("knows","created")
==> {"label":"created","pk":"1","sk":"3","weight":0.4}
==> {"label":"knows","pk":"1","sk":"4","weight":1.0}
==> {"label":"knows","pk":"1","sk":"2","weight":0.5}
P
功能:(函数)描述比较逻辑。
格式
类型 | 名称 | 含义 | 例子 |
基础 | P.eq | 相等 | P.eq(25) |
P.neq | 不相等 | P.neq(25) | |
P.gt | 大于 | P.gt(25) | |
P.gte | 大于等于 | P.gte(25) | |
P.lt | 小于 | P.lt(25) | |
P.lte | 小于等于 | P.lte(25) | |
P.inside | 在范围内:(a, b) | P.inside(25, 32) | |
P.outside | 不在范围内:(-inf, a) U (b, inf) | P.outside(25, 32) | |
P.between | 在之间:[a, b) | P.between(25, 32) | |
P.within | 在集合内 | P.within(25, 32, 33, 35) | |
P.without | 不在集合内 | P.without(25, 32, 33, 35) | |
合成 | and | 与 | P.gt(25) and P.lt(30) |
or | 或 | P.eq(25) or P.eq(30) | |
negate | 反 | P.eq(25).negate() |
备注
仅支持数字类型和string
适用于
is()
、has()
等filter类型的单步P
和表达式的区别P
:适用于一个参数的场景,参数可以没有名字表达式:适用于多个参数的场景,参数必须有名字
二者的功能存在部分重叠,用户可以量体裁衣
// 年龄为27或者至少有两个朋友的人
g("thinkerpop").V("1;2;4;6").hasLabel("person").or(outE("knows").count().is(P.gte(2)),values("age").is(P.eq(27)))
==> {"label":"person","age":29,"name":"marko","pk":"1"}
==> {"label":"person","age":27,"name":"vadas","pk":"2"}
// 等同于
// or()的第一个子遍历没有名字,只能使用P;第二个参数为age,可以通过filter使用表达式代替
g("thinkerpop").V("1;2;4;6").hasLabel("person").or(outE("knows").count().is(P.gte(2)),filter("age=27"))
path
功能(map):返回遍历的路径
备注
path()
仅展示每个单步的结果。如果out()
需要展示边的信息,则需要显示地使用outE().inV()
单步可以被
by()
修饰,用于指定路径上需要记录的字段单步可以定制
PathRecordStrategy
策略,用于指定路径需要记录的信息类型
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").out().out().values("name").path()
==> {"value":[{"label":"person","age":29,"name":"marko","pk":"1"},{"label":"person","age":32,"name":"josh","pk":"4"},{"label":"software","lang":"java","name":"lop","pk":"3"},"lop"],"labels":[[],[],[],[]]}
==> {"value":[{"label":"person","age":29,"name":"marko","pk":"1"},{"label":"person","age":32,"name":"josh","pk":"4"},{"label":"software","lang":"java","name":"ripple","pk":"5"},"ripple"],"labels":[[],[],[],[]]}
// 显式调用outE().inV(),展示边的信息
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").outE().inV().outE().inV().values("name").path()
==> {"value":[{"label":"person","age":29,"name":"marko","pk":"1"},{"label":"knows","pk":"1","sk":"4","weight":1.0},{"label":"person","age":32,"name":"josh","pk":"4"},{"label":"created","pk":"4","sk":"3","weight":0.4},{"label":"software","lang":"java","name":"lop","pk":"3"},"lop"],"labels":[[],[],[],[],[],[]]}
==> {"value":[{"label":"person","age":29,"name":"marko","pk":"1"},{"label":"knows","pk":"1","sk":"4","weight":1.0},{"label":"person","age":32,"name":"josh","pk":"4"},{"label":"created","pk":"4","sk":"5","weight":1.0},{"label":"software","lang":"java","name":"ripple","pk":"5"},"ripple"],"labels":[[],[],[],[],[],[]]}
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").out().out().path().by("name")
==> {"value":["marko","josh","lop"],"labels":[[],[],[]]}
==> {"value":["marko","josh","ripple"],"labels":[[],[],[]]}
PathRecordStrategy
功能:(策略)定制
path()
记录的信息类型格式:信息类型分为下列三种
此策略为IGraph自研扩展的策略
PathRecord.vertex
:顶点PathRecord.edge
:边PathRecord.map
:map类型
备注:
默认记录所有信息类型
策略需要与
withStrategies()
联合使用策略有利于减少数据的传输量
// 默认记录所有信息类型
g("thinkerpop").V("4").hasLabel("person").outE().inV().path()
==> {"value":[{"label":"person","age":32,"name":"josh","pk":"4"},{"label":"created","pk":"4","sk":"3","weight":0.4},{"label":"software","lang":"java","name":"lop","pk":"3"}],"labels":[[],[],[]]}
==> {"value":[{"label":"person","age":32,"name":"josh","pk":"4"},{"label":"created","pk":"4","sk":"5","weight":1.0},{"label":"software","lang":"java","name":"ripple","pk":"5"}],"labels":[[],[],[]]}
// 只记录顶点信息
g("thinkerpop").V("4").withStrategies(PathRecordStrategy(PathRecord.vertex)).hasLabel("person").outE().inV().path()
==> {"value":[{"label":"person","age":32,"name":"josh","pk":"4"},{"label":"software","lang":"java","name":"lop","pk":"3"}],"labels":[[],[]]},
==> {"value":[{"label":"person","age":32,"name":"josh","pk":"4"},{"label":"software","lang":"java","name":"ripple","pk":"5"}],"labels":[[],[]]}
// 只记录边信息
g("thinkerpop").V("4").withStrategies(PathRecordStrategy(PathRecord.edge)).hasLabel("person").outE().inV().path()
==> {"value":[{"label":"created","pk":"4","sk":"3","weight":0.4}],"labels":[[]]}
==> {"value":[{"label":"created","pk":"4","sk":"5","weight":1.0}],"labels":[[]]}
project
功能:(map)单步可以将输入objects映射成map<string,object>
备注:单步可以被
by()
修饰,用于指定映射的value值
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").project("a","b").by(outE("knows").count()).by("age").order().by(select("b"))
==> {"\"a\"":0,"\"b\"":27}
==> {"\"a\"":2,"\"b\"":29}
==> {"\"a\"":0,"\"b\"":32}
==> {"\"a\"":0,"\"b\"":35}
// 每个人创造的物品数量和认识的朋友数量
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").project("created","knows").by(outE("created").count()).by(outE("knows").count())
==> {"\"created\"":1,"\"knows\"":2}
==> {"\"created\"":2,"\"knows\"":0}
==> {"\"created\"":0,"\"knows\"":0}
==> {"\"created\"":1,"\"knows\"":0}
properties
功能:(map)返回字段名和字段值
备注:
支持指定返回,默认返回所有
values()
支持返回字段值
g("thinkerpop").V("1;2").hasLabel("person").properties()
==> {"age":29}
==> {"name":"marko"}
==> {"pk":"1"}
==> {"age":27}
==> {"name":"vadas"}
==> {"pk":"2"}
g("thinkerpop").V("1;2").hasLabel("person").properties("name","age")
==> {"age":29}
==> {"name":"marko"}
==> {"age":27}
==> {"name":"vadas"}
propertyMap
功能:(map)返回字段名和字段值的map
备注:支持指定返回,默认返回所有
g("thinkerpop").V("1;2").hasLabel("person").propertyMap()
==> {"\"age\"":{"age":29},"\"name\"":{"name":"marko"},"\"pk\"":{"pk":"1"}}
==> {"\"age\"":{"age":27},"\"name\"":{"name":"vadas"},"\"pk\"":{"pk":"2"}}
g("thinkerpop").V("1;2").hasLabel("person").propertyMap("name","age")
==> {"\"age\"":{"age":29},"\"name\"":{"name":"marko"}}
==> {"\"age\"":{"age":27},"\"name\"":{"name":"vadas"}}
PushDownStrategy
功能:(策略)指定获取sideEffect的单步下推至存储层执行
备注:在偏计算的场景,将获取sideEffect的单步下推至存储层执行,有利于减少数据的传输
此策略为IGraph自研扩展的策略
// 每个人和其他人年龄乘积的最大值
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").aggregate("x").by("age").V("1;2;3;4;5;6").hasLabel("person").values("age").as("y").local(select("x").unfold().math("_ * y").max())
==> 1015
==> 1120
==> 945
==> 1225
// 将计算最大值的逻辑下推到“获取y之后立刻执行计算”,减少y需要保存的时长
g("thinkerpop").withStrategies(PushDownStrategy("x")).V("1;2;3;4;5;6").hasLabel("person").aggregate("x").by("age").V("1;2;3;4;5;6").hasLabel("person").values("age").as("y").local(select("x").unfold().math("_ * y").max())
==> 1015
==> 1120
==> 945
==> 1225
range
功能:(filter)截断。
格式:
range(low,high)
,low
为uint32类型,high
为int64类型,建议high<50000
。备注:如果
high
为-1的话,则返回low
往后的所有结果;否则,high>low
必须成立。
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").order().by("pk").range(1,2)
==> {"label":"person","age":27,"name":"vadas","pk":"2"}
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").order().by("pk").range(1,-1)
==> {"label":"person","age":27,"name":"vadas","pk":"2"}
==> {"label":"person","age":32,"name":"josh","pk":"4"}
==> {"label":"person","age":35,"name":"peter","pk":"6"}
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").order().by("pk").range(1,0)
==> {"ErrorCode":20040,"ErrorDescription":"gremlin 'range(global)' step invalid (low(1) > high(0) in 'range')"}
repeat
功能:(branch)循环遍历
备注:
单步可以和
times()
、util()
等联合使用,以指定循环停止的条件。单步可以和
emit()
联合使用,用于记录循环的中间结果。出于系统保护的考虑,请不要执行bad query。例如:在有环图中无限制的repeat。
出于系统保护的考虑,请在循环内的每一次跳转指定
limit()
截断,每一度都不能超过5w个结果。
# 经过两次out,得到遍历路径。
g("thinkerpop").V("1").hasLabel("person").repeat(out()).times(2).path().by("name")
==> {"value":["marko","josh","lop"],"labels":[[],[],[]]}
==> {"value":["marko","josh","ripple"],"labels":[[],[],[]]}
# 禁止在 有环图 中执行until
# 从指定节点出发,进行广度优先搜索,直到遇到ripple节点为止。
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").until(has("name","ripple")).repeat(out()).path().by("name")
==> {"value":["marko","josh","ripple"],"labels":[[],[],[]]}
==> {"value":["josh","ripple"],"labels":[[],[]]}
# emit() - 遍历两度,并且中间遇到的路径输出出来。
g("thinkerpop").V("1").hasLabel("person").repeat(out()).times(2).emit().path().by("name")
==> {"value":["marko","lop"],"labels":[[],[]]}
==> {"value":["marko","josh"],"labels":[[],[]]}
==> {"value":["marko","vadas"],"labels":[[],[]]}
==> {"value":["marko","josh","lop"],"labels":[[],[],[]]}
==> {"value":["marko","josh","ripple"],"labels":[[],[],[]]}
# emit() - 遍历两度,并且中间遇到的路径输出出来:包含还没有开始进行repeat的时候的路径。
g("thinkerpop").V("1").hasLabel("person").emit().repeat(out()).times(2).path().by("name")
==>[marko]
==> {"value":["marko"],"labels":[[]]}
==> {"value":["marko","lop"],"labels":[[],[]]}
==> {"value":["marko","josh"],"labels":[[],[]]}
==> {"value":["marko","josh","lop"],"labels":[[],[],[]]}
==> {"value":["marko","josh","ripple"],"labels":[[],[],[]]}
==> {"value":["marko","vadas"],"labels":[[],[]]}
sack
功能:(map)返回实体的sack值
备注:sack值的初始化值、分裂规则和合并规则详见
withSack()
sample
功能:(filter)采样
格式:
sample([Sample.upsampling,][Sample.duplicatable,]NUM)[by(field)]
,NUM
为uint32类型Sample.duplicatable
指定不去重,允许输出object的bulk超过其输入bulk。即输入a a b c,采样3,去重最多得到2个a,不去重可能得到3个a。Sample.upsampling
指定上采样,当输入的object的bulk总和小于采样数时,上采样可以保证一定会返回指定个数的结果(除非0结果)。如果上采样实际生效了,那么指定不去重会失效。默认去重且不上采样。
备注:
默认随机采样。
单步可以被
by()
修饰,用于指定某个字段的值作为采样权重,权重越高采样到的概率越大。
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").outE("created").sample(Sample.upsampling,Sample.duplicatable,5).by("weight")
==> {"label":"created","pk":"1","sk":"3","weight":0.4}
==> {"label":"created","pk":"4","sk":"5","weight":1.0}
==> {"label":"created","pk":"4","sk":"5","weight":1.0}
==> {"label":"created","pk":"4","sk":"5","weight":1.0}
==> {"label":"created","pk":"6","sk":"3","weight":0.2}
select
功能:(map)返回
as()
打标的标签值备注:
单步获取多个标签值时会得到
map<label,objects>
。单步可被
by()
修饰,用于指定获取标签的某个字段。单步可以和
Pop.first
、Pop.last
、Pop.all
联合使用,分别代表选择路径上标签的第一次出现、最后一次出现、和所有出现。
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作为输入
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}
// 第一次出现的a标签值
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").as("a").repeat(out().as("a")).times(2).select(Pop.first,"a")
==> {"label":"person","age":29,"name":"marko","pk":"1"}
==> {"label":"person","age":29,"name":"marko","pk":"1"}
// 最后一次出现的a标签值
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").as("a").repeat(out().as("a")).times(2).select(Pop.last,"a")
==> {"label":"software","lang":"java","name":"lop","pk":"3"}
==> {"label":"software","lang":"java","name":"ripple","pk":"5"}
// 所有出现的a标签值,等价于select("a")
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").as("a").repeat(out().as("a")).times(2).select(Pop.all,"a")
==> [{"label":"person","age":29,"name":"marko","pk":"1"},{"label":"person","age":32,"name":"josh","pk":"4"},{"label":"software","lang":"java","name":"lop","pk":"3"}]
==> [{"label":"person","age":29,"name":"marko","pk":"1"},{"label":"person","age":32,"name":"josh","pk":"4"},{"label":"software","lang":"java","name":"ripple","pk":"5"}]
simplePath
功能:(filter)返回无环的路径
备注:
单步可以被
by()
修饰,用于指定有环路径上需要记录的字段cyclePath()
返回有环的路径
g("thinkerpop").V("1").hasLabel("person").out().out().simplePath().path()
==> {"value":[{"label":"person","age":29,"name":"marko","pk":"1"},{"label":"person","age":32,"name":"josh","pk":"4"},{"label":"software","lang":"java","name":"lop","pk":"3"}],"labels":[[],[],[]]}
==> {"value":[{"label":"person","age":29,"name":"marko","pk":"1"},{"label":"person","age":32,"name":"josh","pk":"4"},{"label":"software","lang":"java","name":"ripple","pk":"5"}
g("thinkerpop").V("1").hasLabel("person").out().out().simplePath().path().by("name")
==> {"value":["marko","josh","lop"],"labels":[[],[],[]]}
==>{"value":["marko","josh","ripple"],"labels":[[],[],[]]}
store
功能:(sideEffect)在遍历过程中,将输入objects聚合成一个list<object>,并保存在sideEffect。
备注:
单步不会影响输入objects,下一个单步仍然以objects作为输入。
单步生成的list<object>是只读的,在后续遍历的任意位置可以通过
cap()
取值。PS:不推荐通过
select()
取值。由于select()
对每个实体都会返回一个list<object>,多个实体就会返回多个一样的list<object>。
单步可以被
by()
修饰,用于指定聚合的字段值。使用
aggregate()
可以阻塞地实现聚合。
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").store("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").store("x").by("name").cap("x")
==> ["josh","marko","peter","vadas"]
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").store("x").by("name").filter("age>=32").cap("x")
==> ["josh","marko","peter","vadas"]
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").store("x").by("name").outE("knows").store("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}]}
sum
功能:(map)计算输入objects的总和。
备注:
单步仅支持数字类型(非
bool
类型)的输入sum(Scope.local)
支持迭代器类型的输入,并且容器内的元素必须是数字类型(非bool
类型)单步会隐式地插入
barrier()
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").values("age").sum()
==> 123
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").values("age").fold().sum(Scope.local)
==> 123
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").aggregate("x").by("age").cap("x").sum(Scope.local)
==> 123
T
功能:(函数)提取输入元素的信息
格式
T.id:返回实体的pkey字段值
T.label:返回实体的label(在图中对应的label)
T.key:返回元素的字段名
T.value:返回元素的字段值
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").has(T.id,P.eq("1"))
==> {"label":"person","age":29,"name":"marko","pk":"1"}
// 两度跳转之后,没有person了,都是software
g("thinkerpop").V("1").hasLabel("person").out().out().has(T.label,P.eq("person"))
==> 空结果
// 按照字段名进行排序
g("thinkerpop").V("1").hasLabel("person").properties().order().by(T.key)
==> {"age":29}
==> {"name":"marko"}
==> {"pk":"1"}
// 按照字段值进行排序
g("thinkerpop").V("1").hasLabel("person").properties().order().by(T.value)
==> {"age":29}
==> {"pk":"1"}
==> {"name":"marko"}
tail
功能:(filter)截断。保留最后
NUM
个结果。格式:
tail(NUM)
,NUM
为uint32类型,建议NUM<50000
备注
limt()
用于保留前NUM
个结果单步会隐式地插入
barrier()
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").tail(2)
==> {"label":"person","age":27,"name":"vadas","pk":"2"}
==> {"label":"person","age":35,"name":"peter","pk":"6"}
times
功能:(修饰符)指定循环遍历的次数
备注:需要与
repeat()
联合使用