How to insert many mutations in a single GraphQL request?

Hi. We are developing a script to insert a lot of data into Dgraph using GraphQL mutations. Previously, we were generating chunks of RDF N-Quad triples (https://dgraph.io/docs/mutations/triples/). That way we could insert many nodes at once. Recently, we decided to migrate our code and work only with GraphQL. We are doing good so far, but we still don’t know how to achieve that behavior of inserting lots of mutations in a single request. To explain a litte better our scenario, we have thousands (sometimes millions) of records and we are spliting into little blocks of hundreds of records. These little blocks is what we want to bulk insert. The case we want to avoid is looping through all our data and inserting a mutation at a time.

Thanks.

1 Like

If you are inserting many nodes of the same type, you could place them all in input argument of add mutation.
Example: If you are adding many nodes of type User,

mutation{
  addUser(input:[{/*User 1 data*/}, {/*User 2 data*/},....])
}

If the nodes are of multiple different types, you could also add these different mutations to the same GraphQL request.
Example: Adding many nodes of types User and Project,

mutation{
  addUser(input:[{/*User 1 data*/}, {/*User 2 data*/},....])
  addProject(input:[{/*Project 1 data*/}, {/*Project 2 data*/},....])
}

Note that these mutations will be executed separately one after other. i.e. addUser mutation with the given input will take place before addProject mutation.

Currently, there is no such way to insert lots of GraphQL mutations in a bulk loader like way.

How would it look like when using variables and the input type, such as AddAuthorInput? I would want to do something like:

mutation addAuthor($author: [AddAuthorInput!]) {
  addAuthor(input: [$author]) {
    author{
      id
      name
    }
  }
}

variables:

{
	"author": [
        {
		"id": "id1",
	       "name": "George Lucas"
         },
         {
		    "id": "id2",
	        "name": "George Lucas2"
         }
    ]
}

But this does not seem to work.

The reason it is not working is because $author is of type [AddAuthorInput!] . It should be of type [AddAuthorInput!]! and also, you should be passing input: $author to addAuthor . The reason being that, $author is of the type what input argument should be . There is no need to enclose it in [] ,

I kinda get it.

For instance, this is my type:

type Author {
    id: String! @id
    name: String @search(by: [term])
}

This is my mutation:

mutation ($author: [AddAuthorInput!]!) {
  addAuthor(input: [$author]) {
    author{
      id name
    }
  }
}

This is my variables object JSON:

{
	"author": [
    {
      "id": "id1",
      "name": "George Lucas"      
    },
    {
      "id": "id2",
      "name": "George Lucas2"      
    }
  ]
}

When I run the mutation, I get this error:

{
  "errors": [
    {
      "message": "Variable type provided [AddAuthorInput!]! is incompatible with expected type AddAuthorInput!",
      "locations": [
        {
          "line": 80,
          "column": 21
        }
      ]
    },
    {
      "message": "Variable \"$author\" of type \"[AddAuthorInput!]!\" used in position expecting type \"AddAuthorInput!\".",
      "locations": [
        {
          "line": 80,
          "column": 21
        }
      ]
    }
  ]
}

I’m not finding the exact place to make the change.

Do I need to create a new input type for getting the outcome? If so, how would it look like?

Ah. This could be because of version or schema difference. I am using similar schema with master version and it forbids me from having $author of type [AddAuthorInput!] . In your case, I think you should use [AddAuthorInput!] .
You will also need to change the argument from input:[$author] to input:$author to make this work.

I see. When I make the changes you suggest I get this other error:

{
  "errors": [
    {
      "message": "Variable type provided [AddAuthorInput!] is incompatible with expected type [AddAuthorInput!]!",
      "locations": [
        {
          "line": 80,
          "column": 20
        }
      ]
    },
    {
      "message": "Variable \"$author\" of type \"[AddAuthorInput!]\" used in position expecting type \"[AddAuthorInput!]!\".",
      "locations": [
        {
          "line": 80,
          "column": 20
        }
      ]
    }
  ]
}

My Dgraph version is v20.07.1.

Oh. I now get it. The problem was not with $author: [AddAuthorInput!]! , but with way $author was passed to input.
I believe if you make the change of $author: [AddAuthorInput!]! , it will work.

1 Like

Yes!!! Now it works! :grinning: :partying_face: :tada:

I will leave here the mutation that worked out.

Mutation:

mutation ($author: [AddAuthorInput!]!) {
  addAuthor(input: $author) {
    author{
      id name
    }
  }
}

Variables:

{
	"author": [
    {
      "id": "id1",
      "name": "George Lucas"      
    },
    {
      "id": "id2",
      "name": "George Lucas2"      
    }
  ]
}

Thank you for your help @rajas !

4 Likes