Gremlin多值属性示例

本文为您介绍Gremlin多值属性示例。

多值属性

  • Gremlin语法中对顶点提供了多值属性支持,在添加或者更新属性时可以通过cardinality参数指定属性的类型。

  • Gremlin提供了两种类型的多值属性:set和list。GDB从1.0.20版本开始支持set属性。

注意事项

  • 只有顶点支持多值属性,边不支持。

  • 一个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

  • 用法1:

    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',
                               'g',
                               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()
  • 用法2:

    from gremlin_python.driver import client
    
    client = client.Client('ws://HOST:PORT/gremlin',
                           'g',
                           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); });
      });