Unable to create an edge between two existing nodes

Moved from GitHub dgraph-js/28

Posted by cajus:

I’ve just started to play around with the JS client for dgraph. Now I’d like link two nodes by a managed edge like so:

{
  set {
    <0x109> <managed> <0x108> .
  }
}

That works fine in Ratle, but fails with JS:

    const txn = dgraphClient.newTxn();

    try {
        // Add test managed reference
        let p = {
          "uid": "0x109",
          "managed": {
            "uid": "0x108"
          }
        };

        // Run mutation.
        const mu = new dgraph.Mutation();
        mu.setSetJson(p);
        txn.mutate(mu);

        // Commit transaction.
        await txn.commit();
    } finally {
        // Clean up. Calling this after txn.commit() is a no-op
        // and hence safe.
        await txn.discard();
    }

which results in:

{"setJson":"eyJ1aWQiOiIweDEwOSIsIm1hbmFnZWQiOnsidWlkIjoiMHgxMDgifX0=","deleteJson":"","setNquads":"","delNquads":"","setList":[],"delList":[],"startTs":0,"commitNow":false,"ignoreIndexConflict":false}
ERROR:  Error: Transaction has been aborted. Please retry
    at Object.<anonymous> (/home/cajus/tmp/dgraph/node_modules/dgraph-js/lib/errors.js:5:23)
    at Module._compile (module.js:660:30)
    at Object.Module._extensions..js (module.js:671:10)
    at Module.load (module.js:573:32)
    at tryModuleLoad (module.js:513:12)
    at Function.Module._load (module.js:505:3)
    at Module.require (module.js:604:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/home/cajus/tmp/dgraph/node_modules/dgraph-js/lib/client.js:39:16)
    at Module._compile (module.js:660:30)
Mutate response:
{"uidsMap":[],"context":{"startTs":211,"commitTs":0,"aborted":false,"keysList":["32fytna3wc2o4"],"linRead":{"idsMap":[[1,164]]}},"latency":{"parsingNs":26030,"processingNs":8052878,"encodingNs":0}}

As I’m not yet completely familiar with the client, I’m wondering what the error means - and how I can get some more information out of it than the setDebugMode(true) offers.

cajus commented :

What’s also not possible but mentioned in the dgraph mutation docs is a construct like this:

[
  {
    "uid": "_:foo",
    "name": "foo"
  },
  {
    "name": "bar",
    "managed": "_:foo"
  }
]

Error: 2 UNKNOWN: Input for predicate managed of type uid is scalar

cajus commented :

The schema for managed is:

managed: uid @reverse @count .

If I delete it, dgraph creates a new schema entry which looks like that:

managed: string .

It even creates a string entry if I explicitly use grpc with uid_val:

// reference
let nqRef = new NQuad();
nqRef.subject = '_:foo';
nqRef.predicate = 'managed';
nqRef.object_value = new Value().set('uid_val', parseInt('0x14a'));

pawanrawal commented :

The JSON has to be something like

  {
    "uid": "_:bar",
    "name": "bar",
    "managed": {
       "uid": "_:foo",
     }
  }

All the values that are part of the object are considered as scalar values for the node. For it to be a linked node, it has to link to another object using the predicate.

cajus commented :

Sorry the one post was just an iteration about trying various ways to make it work. It was wrong, yes. If you take a look at Unable to create an edge between two existing nodes · Issue #28 · dgraph-io/dgraph-js · GitHub, the syntax was correct. That works fine if the nodes are referenced inside of one mutation.

But: I’d like to add a managed edge between two existing nodes. If I take your example and replace _:* by 0x122 and 0x123 (the uids of existing nodes), it does not work:

  {
    "uid": "0x122",
    "managed": {
       "uid": "0x123",
     }
  }

That does neither work with direct grpc, nor with the dgraph-js. But works if I directly make a curl or ratel request. So there must either be something wrong in the syntax I’m using for referencing existing nodes, or there is a bug somewhere.

pawanrawal commented :

Do you get this error Transaction has been aborted. Please retry or some other error while using dgraph-js?

cajus commented :

Just a second. I’ll put up a modified version of the dgraph-js example. Code tells more than my broken english is able to do :wink:

cajus commented :

Take a look at this repo. Run npm install and node dgraph.js for the dgraph-js variant. And node grpc.js for the grpc variant. Requires a local dgraph instance at port 9080.

pawanrawal commented :

Ok, this was an interesting one. You were missing an await before the second mutate because of which Commit was called before Mutate returned.

Commit here should return an error since StartTs was zero, the error being returned currently was misleading. I have submitted a fix to master with Return error from Commit if startTs is zero · dgraph-io/dgraph@c7a66bd · GitHub which returns a better error message.

cajus commented :

Doh. I didn’t catch that one. Thanks for your help!