Help understanding Upsert - How to Commit Mutations/Upserts

I am still struggling to understand upserts

I have the following query that finds all of the uids that I want to update:

{
  groupNote(func: has(Note.access)) @filter(eq(Note.isPublic, true)) @cascade {
    uid
    Note.isPublic
    Note.access {
      uid
      ACL.grants {
        uid
        Contact.isGroup {
          uid
          Group.slug
        }
      }
    }
  }
}

This query works perfect. So I want to change the Note.isPublic to false. I figured that would be simple for an upsert…

upsert {
  query {
    groupNote as var(func: has(Note.access)) @filter(eq(Note.isPublic, true)) @cascade {
      uid
      Note.isPublic
      Note.access {
        uid
        ACL.grants {
          uid
          Contact.isGroup {
            uid
            Group.slug
          }
        }
      }
    }
  }
  mutation {
    set {
      uid(groupNote) <Note.isPublic> "false" .
    }
  }
}

I get the response

{
  "data": {
    "code": "Success",
    "message": "Done",
    "queries": {},
    "uids": {}
  }
}

Which I guess is misleading to me. While it probably did what I told it to do, it did not do what I expected it to do. If I do the originaly query again, I still get the same results, meaning that Note.isPublic was not updated to false

I did it in the meantime by running the query and getting a list of ids manually (over 3K) and then running a graphql mutation with those ids and set the desired field to false.

Did you mean uid(groupNote) here? groupNote is the name of your query variable.

uid(groupNote)  <Note.isPublic> "false" .

Is the actual line I was using. Sorry, I mis-typed in my question.

If I had done this it would have thrown a variables defined/used error.

The example you shared should work, as you’re using the query variable and setting the value. Are you committing the upsert mutation?

This must be where I am going astray…

I am sending the upsert to dgraph (using Slash) to the mutate endpoint with the application/rdf content-type. How do I commit it?

Over the HTTP API, you can set /mutate?commitNow=true for the /mutate endpoint.

For txns with multiple mutations, you can call /commit separately with the appropriate timestamp and txn keys/preds: https://dgraph.io/docs/clients/raw-http/#committing-the-transaction

When you commit, you’ll see the commit_ts in the extensions in the response, e.g.:

{
    "data": { ... },
    "extensions": {
        "txn": {
          "start_ts": 200460131,
          "commit_ts": 200460132,
          ...
        }
    }
}
1 Like

yes, that is what I have been missing. I was reading the docs on Upsert Block and I see now that in passing it mentions,

Execution of an upsert block also returns the response of the query executed on the state of the database before mutation was executed . To get the latest result, we should commit the mutation and execute another query.

I did not understand that clearly enough that I had to do that before the changes were committed, I understood it to mean that in order to get the data after the upsert I would need to run a separate query.

Looking back in the docs at Mutations using cURL I see:

To commit the mutation, pass the parameter commitNow=true in the URL.

A link to committing mutations should probably be on the Upsert Block doc page, now that it is a separate page by itself (I think it used to be one big doc page for Mutations). Maybe even a page dedicated to “Committing Mutations” inside of the Mutation docs that can then be linked to from anywhere discussing the need to commit before changes become “live”

2 Likes