Single operation increment / decrement numbers

Hello,

Is it possible or is there any plan to support increasing or decreasing number values by a certain amount in a single mutation operation?

For instance, increasing a counter or a score.

This function does not exist for Mutation. What you can do is to do a query requesting the current Score + 1 (or - 1). Then you will create a mutation according to that value that comes. Actually there are no functions in Mutations, just Queries. With the exception of Delete mutation.

e.g:

{ # this is just an example, it is not functional

	ScorePhilosopher(func: uid(0x485441)) {
        F as philosopher.score
		scorePlus : math(F + 1)
	}
}

And then with this result of “scorePlus : math (F + 1)”, you can create a mutation for the same UID.
That would be the closest form to what you want. Personally I find it difficult to create this feature in the short term or if it’s worth it.

PS: But this form can give conflict problem, more than one people can request + 1 at the same time and this can generate conflicts.

Thank you for your response.

Indeed as there is no such update function, then if multiple simultaneous updates occur on that score, I need to add an @upsert index on it and do a query/mutation transaction.

That’s why it would be easier to have an atomic increment update like in SQL:

UPDATE myTable
SET SCORE = SCORE + 1

:slight_smile:

1 Like

Yes, Upserts are the best way to approach this. Because it can handle conflicts, it just does not increment or decrement https://docs.dgraph.io/howto/#conflicts

If you find it necessary,open an Issue requesting this feature on Github, pointing out this discuss and with an argumentative resume.

1 Like

If there are conflicts, Dgraph transactions would ensure that only one of the multiple simultaneous requests would succeed. Dgraph supports ACID transactions (there’s one bug in there that we’re currently fixing, but that’s the aim).

2 Likes

Thank you, I’ll do it with upserts.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.

Dgraph has upsert blocks now, so you can do these updates in a single request:

upsert {
  query {
    counter(func: has(counter.val)) {
      old: A as counter.val
      new: B as math(A+1)
    }
  }
  mutation @if(gt(len(A), 0)) {
    set {
      uid(A) <counter.val> val(B) .
    }
  }
}

Example response:

{
  "data": {
    "code": "Success",
    "message": "Done",
    "queries": {
      "counter": [
        {
          "old": 10,
          "new": 11
        }
      ]
    },
    "uids": {}
  },
4 Likes