Skip to content

Upsert should always return the uid #73

@pepoospina

Description

@pepoospina

Experience Report

What you wanted to do

I am using an upsert operation as described in dgraph-js to get or create a new node with a given external id called did and return its uid.

What you actually did

This is my code. It works the first time the node with the external id did does not exist. But it fails if it does exist.

    const mu = new dgraph.Mutation();
    const req = new dgraph.Request();

    let query = `profile as var(func: eq(did, "${did}"))`;
  
    req.setQuery(`query{${query}}`);

    let nquads = `uid(profile) <did> "${did}" .`;
    nquads = nquads.concat(`\nuid(profile) <dgraph.type> "${PROFILE_SCHEMA_NAME}" .`);

    mu.setSetNquads(nquads);
    req.setMutationsList([mu]);
    req.setCommitNow(true);

    let response = await this.client.newTxn().doRequest(req);
    let uid = response.getUidsMap().get("uid(profile)")
    return uid;

Why that wasn't great, with examples

I will have to add new logic to my function to consider the case in which the result is empty and run a new query to get the uid of that did.

I don't like how that if looks inside my function. Is that a code smell? Should the upsert return the uid even if it did not create it?

This is my updated function

    const mu = new dgraph.Mutation();
    const req = new dgraph.Request();

    let query = `profile as var(func: eq(did, "${did}"))`;
  
    req.setQuery(`query{${query}}`);

    let nquads = `uid(profile) <did> "${did}" .`;
    nquads = nquads.concat(`\nuid(profile) <dgraph.type> "${PROFILE_SCHEMA_NAME}" .`);

    mu.setSetNquads(nquads);
    req.setMutationsList([mu]);
    req.setCommitNow(true);

    let response = await this.client.newTxn().doRequest(req);
    let uid = response.getUidsMap().get("uid(profile)")

    if (!uid) {
        // it already existed. query for it.
        const didQuery = `
        query {
            profile(func: eq(did, "${did}")) {
              uid
            }
        }
        `;
        let result = await this.client.newTxn().query(didQuery);
        let profile = result.getJson().profile[0];
        uid = profile.uid;
    }

    return uid;

Any external references to support your case

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions