Gremlin语法中对顶点提供了多值属性,本文介绍多值属性的用法。
背景信息
关于多值属性,请参见 多值属性 。
注意事项
- 只有顶点支持多值属性,边不支持。
- 一个Set属性的多个value可以是不同类型,但是图数据库GDB在判断值是否相同时是按照语义进行比较的,类型不同但是值相等的两个value会被认为是相同的(例如1和1.0),因而只会保留一个。
- 属性的cardinality可以改变,以最后一次调用property()更新属性为准。Set属性更新为single类型后,只保留后者的值;single属性更新为Set类型后,前后两个值都保留。
- Set属性查询结果中的多个值是按照语义排序的。如果是数值型,按值升序排列;如果是字符串型,按字典序排列。
- Set属性和single属性一样,会自动建立索引,查询性能跟single属性相近。
Set属性用法
-
Console
-
设置属性
g.addV('person'). property(id, '11111'). property('name', 'marko'). property(set, 'email', 'marko@a.com'). property(set, 'email', 'marko@b.com')
-
查询属性
g.V('11111').properties('email') ==>vp[email->marko@a.com] ==>vp[email->marko@b.com]
-
删除一个值
g.V('11111').properties('email').hasValue('marko@a.com').drop()
-
删除所有值
g.V('11111').properties('email').drop()
-
设置属性
-
Java
package com.gdb.alibaba; import org.apache.tinkerpop.gremlin.driver.Cluster; import org.apache.tinkerpop.gremlin.driver.Client; import org.apache.tinkerpop.gremlin.driver.Result; import org.apache.tinkerpop.gremlin.driver.ResultSet; import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertex; import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertexProperty; import java.util.List; import java.util.Map; import java.util.HashMap; import java.io.File; public class Test { public static void main(String[] args) { try { if (args.length != 1) { System.out.println("gdb-remote.yaml path needed"); return; String yaml = args[0]; Cluster cluster = Cluster.build(new File(yaml)).create(); Client client = cluster.connect().init(); String dsl = "g.addV(yourLabel).property(propertyKey, propertyValue).property(set, setPropertyKey, setPropertyValue0).property(set, setPropertyKey, setPropertyValue1)"; Map<String, Object> parameters = new HashMap<>(); parameters.put("yourLabel", "person"); parameters.put("propertyKey", "name"); parameters.put("propertyValue", "marko"); parameters.put("setPropertyKey", "email"); parameters.put("setPropertyValue0", "marko@a.com"); parameters.put("setPropertyValue1", "marko@b.com"); ResultSet results = client.submit(dsl, parameters); List<Result> result = results.all().join(); if (result.size() > 0) { String vertexId = (String) ((DetachedVertex) result.get(0).getObject()).id(); parameters.put("yourId", vertexId); dsl = "g.V(yourId).properties(setPropertyKey)"; results = client.submit(dsl, parameters); result = results.all().join(); result.forEach(r -> { Object element = r.getObject(); if (element instanceof DetachedVertexProperty) { DetachedVertexProperty property = (DetachedVertexProperty) element; System.out.println(property.key() + ": " + property.value()); cluster.close(); } catch (Exception e) { System.out.println(e.getMessage()); }
-
Python
方法一
from gremlin_python.process.anonymous_traversal import traversal from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection from gremlin_python.process.traversal import T, Cardinality g = traversal().withRemote( DriverRemoteConnection('ws://HOST:PORT/gremlin', username=USER, password=PASS)) v = g.addV('person').property(T.id_, "123").property("name", "marko") \ .property(Cardinality.set_, "email", "marko@gmail.com") \ .property(Cardinality.set_, "email", "marko@hotmail.com").iterate() properties = g.V('123').properties('email') for prop in properties: print(prop.key + ": " + str(prop.value)) g.V('123').drop().iterate()
方法二
from gremlin_python.driver import client client = client.Client('ws://HOST:PORT/gremlin', username=USER, password=PASS) dsl = 'g.addV("person").property(id, "123").property("name", "marko").property(set, "email", "marko@a.com").property(set, "email", "marko@b.com")' callback = client.submitAsync(dsl) for result in callback.result(): print(result) dsl = 'g.V("123").properties("email")' callback = client.submitAsync(dsl) for result in callback.result(): for prop in result: print(prop.key + ": " + str(prop.value))
-
Go
bindings := make(map[string]interface{}) bindings["GDB___id"] = "22" bindings["GDB___label"] = "goTest" bindings["GDB___PK"] = "name" bindings["GDB___PV"] = "Jack" bindings["GDB___PK_PHONE"] = "phone" bindings["GDB___PV_PHONE1"] = "111111" bindings["GDB___PV_PHONE2"] = "222222" dsl := "g.addV(GDB___label).property(id, GDB___id).property(GDB___PK, GDB___PV).property(set, GDB___PK_PHONE, GDB___PV_PHONE1).property(set, GDB___PK_PHONE, GDB___PV_PHONE2)" results, err := client.SubmitScriptBound(dsl, bindings) if err != nil { log.Fatalf("Error while querying: %s\n", err.Error()) // get response, add vertex should return a Vertex for _, result := range results { v := result.GetVertex() log.Printf("get vertex: %s", v.String()) // read vertex property for _, p := range v.VProperties() { log.Printf("prop: %s", p.String()) }
-
Javascript
const gremlin = require('gremlin'); const DriverRemoteConnection = gremlin.driver.DriverRemoteConnection; const Graph = gremlin.structure.Graph; const __ = gremlin.process.statics; const t = gremlin.process.t; const cardinality = gremlin.process.cardinality const authenticator = new gremlin.driver.auth.PlainTextSaslAuthenticator(USER, PASS); const graph = new Graph(); const g = graph.traversal().withRemote( new DriverRemoteConnection('ws://HOST:PORT/gremlin', {authenticator})); g.addV('person') .property(t.id, '2222') .property('name', 'james') .property(cardinality.set, 'phone', '111111') .property(cardinality.set, 'phone', '222222') .iterate() .then(data => { g.V('2222').properties().toList().then( properties => { console.log(properties); });