Search code examples
javascriptgraphgremlintinkerpop

How to create Gremlin query that only updates defined properties?


I want to create a Gremlin query that only updates the vertex properties that I are not undefined in JavaScript-land. The properties on the actual vertices are defined, but my updateUser function might not actually get both firstName and lastName arguments.

Let's say that I have 'user' vertices that have the 'firstName' and 'lastName' properties. When I call my update function, I may specify the new firstName of the user, the new lastName of the user, or both. I have created a query that can handle the scenario when I want to update both properties:

const updateUser = async (id, firstName, lastName) => {

    const { id, firstName, lastName } = userData

    return client.submit(`g.V().hasLabel(label).has('id', id).property(Cardinality.single, 'firstName', firstName).property(Cardinality.single, 'lastName', lastName)`, {
        label: 'user',
        id: id,
        firstName: firstName,
        lastName: lastName
    }).catch(error => {
        throw new Error(error)
    })

}

The problem is, that when, for instance, the firstName variable is undefined, I get the following error: 'Unable to resolve symbol 'firstName' in the current context'. I want to be able to only update one of the values. How can I specify that I want to ignore undefined values?


Solution

  • You can consider whether firstName and lastName are defined when building the traversal string and the bindings object.

    Here is some untested code to explain what I mean.

    let traversal = `g.V().hasLabel(label).has('id', id)`;
    const bindings = {
      label: 'user',
      id: id
    };
    
    if (firstName) {
      traversal += `.property(Cardinality.single, 'firstName', firstName)`;
      bindings.firstName = firstName;
    }
    if (lastName) {
      traversal += `.property(Cardinality.single, 'lastName', lastName)`;
      bindings.lastName = lastName;
    }
    
    client.submit(traversal, bindings);
    

    If you are using a database that supports Gremlin bytecode, your code can be more elegant.

    traversal = g.V().hasLabel(label).has('id', id);
    if (firstName) {
      traversal = traversal.property(Cardinality.single, 'firstName', firstName);
    }
    if (lastName) {
      traversal = traversal.property(Cardinality.single, 'lastName', lastName);
    }