How to use Dgraph to automatically increase ID?

Sometimes, we extract some particular log attributes to be target data which would be stored in DB but without specific names. If in RDB, each of logs can be given an auto-increment primary key as their name. However, I’m not sure what the best practice is in Dgraph.

Take an example.
In MySQL, we can automatically give each run a specific ID by setting an auto-increment primary key. However, if in Dgraph, we need to get the latest run ID by querying and increase them by ourselves.

// for RDB (gorm for mysql)
type Run struct {
	ID         uint      `gorm:"primary_key" json:"id"`
	Output     string    `json:"output"`
	Action     string    `json:"action"`
	Status     string    `json:"status"`
	CreatedAt  time.Time `json:"created_at"`
}

// for dgraph (dgraph schema)
type Run {
	run.id:			int
	run.output:		string
	run.action:		string
	run.status:		string
	run.created_at:	datetime
}
run.id:			int @index(int) .
run.output:		string .
run.action:		string .
run.status:		string .
run.created_at:	datetime .

Is there any other way to automatically increase ID instead of querying and increase them?
Thank you for your help

Hi, dgraph can generate an unique UID for each entity node. This web https://docs.dgraph.io/mutations/#blank-nodes-and-uid may be helpful.

You can try Upsert Block

upsert {
  query {
    ## I'm not sure if "first:-1" would work 
    var(func: has(run.id), first:-1) { 
    getLastID as run.id
    Increment as math(getLastID + 1)
}

  }

  mutation {
    set {
       _:New <run.id> val(Increment) .
       _:New <run.output> " "  .
       _:New <run.action > " "  .
       _:New <run.status > " " .
       _:New <run.created_at > " " .
    }
  }
}
1 Like

Great!!! That’s what I want !!!
Temporarily, we would like to maintain MySQL and Dgraph at the same time.
Due to data consistency, we need to consider some special cases which are appropriate for properties of RDB but not for Dgraph’s.

Thank you for your help :smiling_face_with_three_hearts:

Hi,
I have tried this and it does not seem to really work. run.id predicate is never set.
It makes sense because I dont think you can use val function independently without using uid function.
Is there any other way to do this?

Try this

One thing I’ve noticed is that “first:-1” won’t work, so you need to have a very specific query to increase the “run.id” value.

UPDATE: In fact, it is possible yes, if you use decreasing order. I have updated the query below.

Tested with

Dgraph version   : v20.03.0-beta.20200320
Dgraph SHA-256   : f6e42482ba94525c37bfb5daeb05208f12d01291997e09f2e5d0d8d58baf1751
Commit SHA-1     : cc10d2ad
Commit timestamp : 2020-03-20 16:18:05 -0700
Branch           : release/v20.03
Go version       : go1.14
upsert {
  query {
    q(func: has(run.id), orderdesc:run.id, first:1, offset:0) { 
    getLastID as run.id
}
 me() {
    VD as sum(val(getLastID))
    Increment as math(VD + 1)
  }
  }

  mutation {
    set {
       _:New <run.id> val(Increment) .
       _:New <run.output> "a"  .
       _:New <run.action> "a"  .
       _:New <run.status> "a" .
       _:New <run.created_at> "a" .
    }
  }
}

The result after a first creation

{
  "data": {
    "code": "Success",
    "message": "Done",
    "queries": {
      "q": [
        {
          "run.id": 1
        }
      ],
      "me": [
        {
          "sum(val(getLastID))": 1
        },
        {
          "val(Increment)": 2
        }
      ]
    },
    "uids": {
      "New": "0xaae66"
    }
  }
}

Query

{
  q(func: uid(0xaae66)){
    run.id
    run.output
    run.action
    run.status
    run.created_at
  }
}

Result

{
  "data": {
    "q": [
      {
        "run.id": 2,
        "run.output": "a",
        "run.action": "a",
        "run.status": "a",
        "run.created_at": "a"
      }
    ]
  }
}

Thanks.
I tried to use these, unfortunately run.id does not get set for me.
I guess something to do with dgraph version I am using.

upsert {
  query {
    q(func: has(run.id), orderdesc:run.id, first:1, offset:0) { 
    getLastID as run.id
}
 me() {
    VD as sum(val(getLastID))
    Increment as math(VD + 1)
  }
  }

  mutation {
    set {
       _:New <run.id> val(Increment) .
       _:New <run.output> "a"  .
       _:New <run.action> "a"  .
       _:New <run.status> "a" .
       _:New <run.created_at> "2006" .
    }
  }
}
{
  "data": {
    "q": [
      {
        "run.output": "a",
        "run.action": "a",
        "run.status": "a",
        "run.created_at": "2006-01-01T00:00:00Z"
      }
    ]
  },
  "extensions": {
    "server_latency": {
      "parsing_ns": 139300,
      "processing_ns": 13521300,
      "encoding_ns": 82700,
      "assign_timestamp_ns": 3415600,
      "total_ns": 17686700
    },
    "txn": {
      "start_ts": 4700
    },
    "metrics": {
      "num_uids": {
        "": 1,
        "run.action": 1,
        "run.created_at": 1,
        "run.id": 1,
        "run.output": 1,
        "run.status": 1
      }
    }
  }
}
{
  q(func: uid(0xe60)){
    run.id
    run.output
    run.action
    run.status
    run.created_at
  }
}
{
  "data": {
    "q": [
      {
        "run.output": "a",
        "run.action": "a",
        "run.status": "a",
        "run.created_at": "2006-01-01T00:00:00Z"
      }
    ]
  },
  "extensions": {
    "server_latency": {
      "parsing_ns": 139300,
      "processing_ns": 13521300,
      "encoding_ns": 82700,
      "assign_timestamp_ns": 3415600,
      "total_ns": 17686700
    },
    "txn": {
      "start_ts": 4700
    },
    "metrics": {
      "num_uids": {
        "": 1,
        "run.action": 1,
        "run.created_at": 1,
        "run.id": 1,
        "run.output": 1,
        "run.status": 1
      }
    }
  }
}

Yes, it is the version. You have to use the one I’ve shared. This was a bug recently fixed.

I am using this docker image

image: dgraph/dgraph:v1.2.1

Dgraph version : v1.2.1
Dgraph SHA-256 : 3f18ff84570b2944f4d75f6f508d55d902715c7ca2310799cc2991064eb046f8
Commit SHA-1 : ddcda9296
Commit timestamp : 2020-02-06 15:31:05 -0800
Branch : HEAD
Go version : go1.13.5

See

Thanks, indeed it works on this version.