🔎 We would love to get your feedback on our documentation. May we ask for 3 minutes of your time? Thanks 🙏

/v1/batch

Weaviate on Stackoverflow badge Weaviate issues on Github badge Weaviate v1.14.1 version badge Weaviate v1.14.1 version badge Weaviate total Docker pulls badge

With batch you can upload a lot of data objects in bulk. This saves time compared to a lot of single request.


Batch data objects

For sending data objects to Weaviate in bulk.

Performance

💡 Import speeds, especially for large datasets, will drastically improve when using the batching endpoint.

A few points to bear in mind:

  1. If you use a vectorizer that improves with GPU support, make sure to enable it if possible, it will drastically improve import.
  2. Avoid duplicate vectors for multiple data objects.
  3. Handle your errors, if you ignore them, it might lead to significant delays on import.
  4. If import slows down after 2M objects, consider setting the vectorCacheMaxObjects in your schema. Also, see this example.
  5. There are ways to improve your setup when using vectorizers. Like in the Wikipedia demo dataset. We will keep publishing about this, sign up for our Slack channel to keep up to date.

Method and URL

POST /v1/batch/objects

Parameters

The body requires the following field:

nametyperequireddescription
objectslist of data objectsyesa list of data objects, which correspond to the data object body

Example request

  import weaviate

client = weaviate.Client("http://localhost:8080")

first_object_props = {
    "name": "Jane Doe",
    "writesFor": [{
        "beacon": "weaviate://localhost/f81bfe5e-16ba-4615-a516-46c2ae2e5a80"
    }]
}

second_object_props = {
    "name": "John Doe",
    "writesFor": [{
        "beacon": "weaviate://localhost/f81bfe5e-16ba-4615-a516-46c2ae2e5a80"
    }]
}

# Python client specific configurations can be set with `client.batch.configure`
# the settings can be applied to both `objects` AND `references`.
# You have to only set them once.
client.batch.configure(
  # `batch_size` takes an `int` value to enable auto-batching
  # (`None` is used for manual batching)
  batch_size=100, 
  # dynamically update the `batch_size` based on import speed
  dynamic=False,
  # `timeout_retries` takes an `int` value to retry on time outs
  timeout_retries=3,
  # checks for batch-item creation errors
  callback=None,
)

with client.batch as batch:
  # Add object without a custom vector.
  # When using vectorization modules this can be used
  # or when you don't want to set a vector
  batch.add_data_object(first_object_props, 'Author', "36ddd591-2dee-4e7e-a3cc-eb86d30a4303")
  # Add object with a custom vector
  batch.add_data_object(second_object_props, 'Author', "36ddd591-2dee-4e7e-a3cc-eb86d30a4304", vector=[0.1, 0.2, 0.3])
  const weaviate = require("weaviate-client");

const client = weaviate.client({
  scheme: 'http',
  host: 'localhost:8080',
});

var toImport = [{
  class: "Author",
  id: '36ddd591-2dee-4e7e-a3cc-eb86d30a4303',
  properties: {
    name: "Jane Doe",
    writesFor: [{
      beacon: "weaviate://localhost/f81bfe5e-16ba-4615-a516-46c2ae2e5a80"
    }]
  }
},
{
  class: "Author",
  id: '36ddd591-2dee-4e7e-a3cc-eb86d30a4304',
  properties: {
    name: "John Doe",
    writesFor: [{
      beacon: "weaviate://localhost/f81bfe5e-16ba-4615-a516-46c2ae2e5a80"
    }]
  }
}];

client.batch
  .objectsBatcher()
  .withObject(toImport[0])
  .withObject(toImport[1])
  .do()
  .then(res => {
      console.log(res)
  })
  .catch(err => {
      console.error(err)
  });

/* The following is also possible:
const weaviate = require("weaviate-client");

const client = weaviate.client({
  scheme: 'http',
  host: 'localhost:8080',
});

const toImport = [
  client.data
    .creator()
    .withClassName('Author')
    .withId('36ddd591-2dee-4e7e-a3cc-eb86d30a4303')
    .withProperties({
      name: "Jane Doe",
      writesFor: [{
        beacon: "weaviate://localhost/f81bfe5e-16ba-4615-a516-46c2ae2e5a80"
      }]
    })
    .payload(), // note the .payload(), not .do()!
  client.data
    .creator()
    .withClassName('Author')
    .withId('36ddd591-2dee-4e7e-a3cc-eb86d30a4304')
    .withProperties({
      name: "John Doe",
      writesFor: [{
        beacon: "weaviate://localhost/f81bfe5e-16ba-4615-a516-46c2ae2e5a80"
      }]
    })
    .payload(), // note the .payload(), not .do()!
  ];

client.batch
      .objectsBatcher()
      .withObject(toImport[0])
      .withObject(toImport[1])
      .do()
      .then(res => {
        console.log(res)
      })
      .catch(err => {
          console.error(err)
      });
*/
  package main

import (
  "context"
  "fmt"

  "github.com/semi-technologies/weaviate-go-client/v4/weaviate"
  "github.com/semi-technologies/weaviate/entities/models"
)

func main() {
  cfg := weaviate.Config{
    Host:   "localhost:8080",
    Scheme: "http",
  }
  client := weaviate.New(cfg)

  objects := []*models.Object{
    {
      Class: "Author",
      ID:    "36ddd591-2dee-4e7e-a3cc-eb86d30a4303",
      Properties: map[string]interface{}{
        "name": "Jane Doe",
        "writesFor": map[string]string{
          "beacon": "weaviate://localhost/f81bfe5e-16ba-4615-a516-46c2ae2e5a80",
        },
      },
    },
    {
      Class: "Author",
      ID:    "36ddd591-2dee-4e7e-a3cc-eb86d30a4304",
      Properties: map[string]interface{}{
        "name": "John Doe",
        "writesFor": map[string]string{
          "beacon": "weaviate://localhost/f81bfe5e-16ba-4615-a516-46c2ae2e5a80",
        },
      },
    },
  }

  result, err := client.Batch().ObjectsBatcher().
    WithObject(objects[0]).
    WithObject(objects[1]).
    Do(context.Background())

  if err != nil {
    panic(err)
  }
  fmt.Printf("%v", result)
}
  package technology.semi.weaviate;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import technology.semi.weaviate.client.Config;
import technology.semi.weaviate.client.WeaviateClient;
import technology.semi.weaviate.client.base.Result;
import technology.semi.weaviate.client.v1.batch.model.ObjectGetResponse;
import technology.semi.weaviate.client.v1.data.model.WeaviateObject;

public class App {
  public static void main(String[] args) {
    Config config = new Config("http", "localhost:8080");
    WeaviateClient client = new WeaviateClient(config);

    List<WeaviateObject> objects = new ArrayList() {
      {
        add(
          WeaviateObject.builder()
            .className("Author")
            .id("36ddd591-2dee-4e7e-a3cc-eb86d30a4303")
            .properties(new HashMap() {
              {
                put("name", "Jane Doe");
                put("writesFor", new HashMap() {
                  {
                    put("beacon", "weaviate://localhost/f81bfe5e-16ba-4615-a516-46c2ae2e5a80");
                  }
                });
              }
            })
            .build()
        );
        add(
          WeaviateObject.builder()
            .className("Author")
            .id("36ddd591-2dee-4e7e-a3cc-eb86d30a4304")
            .properties(new HashMap() {
              {
                put("name", "John Doe");
                put("writesFor", new HashMap() {
                  {
                    put("beacon", "weaviate://localhost/f81bfe5e-16ba-4615-a516-46c2ae2e5a80");
                  }
                });
              }
            })
            .build()
        );
      }
    };

    Result<ObjectGetResponse[]> result = client.batch().objectsBatcher()
      .withObject(objects.get(0))
      .withObject(objects.get(1))
      .run();

    if (result.hasErrors()) {
      System.out.println(result.getError());
      return;
    }
    System.out.println(result.getResult());
  }
}
  $ curl \
-X POST \
-H "Content-Type: application/json" \
-d '{
  "objects": [{
    "class": "Author",
    "id": "36ddd591-2dee-4e7e-a3cc-eb86d30a4303",
    "properties": {
        "name": "Jane Doe",
        "writesFor": [{
          "beacon": "weaviate://localhost/f81bfe5e-16ba-4615-a516-46c2ae2e5a80"
        }]
    }
  }, {
    "class": "Author",
    "id": "36ddd591-2dee-4e7e-a3cc-eb86d30a4304",
    "properties": {
        "name": "John Doe",
        "writesFor": [{
          "beacon": "weaviate://localhost/f81bfe5e-16ba-4615-a516-46c2ae2e5a80"
        }]
    }
  }]
}' \
http://localhost:8080/v1/batch/objects

Batching objects with the Python Client

Specific documentation for the Python client

Additional documentation

Batch references

For batching cross-references between data objects in bulk.

Method and URL

POST /v1/batch/references

Parameters

The body of the data object for a new object is a list of objects containing:

nametyperequireddescription
fromWeaviate Beacon (long-form)yesThe beacon, in the form of weaviate://localhost/{Classname}/{id}/{cref_property_name}
toWeaviate Beacon (regular)yesThe beacon, in the form of weaviate://localhost/{className}/{id}

Note: In the beacon format, you need to always use localhost as the host, rather than the actual hostname. localhost refers to the fact that the beacon’s target is on the same Weaviate instance, as opposed to a foreign instance.

*Note: For backward compatibility, you can omit the class name in the short-form beacon format that is used for to. You can specify it as weaviate://localhost/. This is, however, considered deprecated and will be removed with a future release, as duplicate IDs across classes could mean that this beacon is not uniquely identifiable. For the long-form beacon - used as part of `from` - you always need to specify the full beacon, including the reference property name.*

Example request

  import weaviate

client = weaviate.Client("http://localhost:8080")

# Python client specific configurations can be set with `client.batch.configure`
# the settings can be applied to both `objects` AND `references`.
# You have to only set them once.
client.batch.configure(
  # `batch_size` takes an `int` value to enable auto-batching
  # (`None` is used for manual batching)
  batch_size=100, 
  # dynamically update the `batch_size` based on import speed
  dynamic=False,
  # `timeout_retries` takes an `int` value to retry on time outs
  timeout_retries=3,
  # checks for batch-item creation errors
  callback=None,
)

with client.batch as batch:
    # Format for batching is as follows:
    # `client.batch.add_reference(<from_entity_uuid>, <from_class_name>, <from_property_name>, <to_entity_uuid>)`
    batch.add_reference("36ddd591-2dee-4e7e-a3cc-eb86d30a4303", "Author", "wroteArticles", "6bb06a43-e7f0-393e-9ecf-3c0f4e129064", "Article")
    batch.add_reference("36ddd591-2dee-4e7e-a3cc-eb86d30a4303", "Author", "wroteArticles", "b72912b9-e5d7-304e-a654-66dc63c55b32", "Article")
  const weaviate = require("weaviate-client");

const client = weaviate.client({
  scheme: 'http',
  host: 'localhost:8080',
});

client.batch
      .referencesBatcher()
      .withReference({
        from: `weaviate://localhost/Author/36ddd591-2dee-4e7e-a3cc-eb86d30a4303/wroteArticles`,
        to: `weaviate://localhost/Article/6bb06a43-e7f0-393e-9ecf-3c0f4e129064`,
        // prior to v1.14 omit the class name as part of the "to" beacon and specify it as weaviate://localhost/<id>
      })
      .withReference({
        from: `weaviate://localhost/Author/36ddd591-2dee-4e7e-a3cc-eb86d30a4303/wroteArticles`,
        to: `weaviate://localhost/Article/b72912b9-e5d7-304e-a654-66dc63c55b32`,
        // prior to v1.14 omit the class name as part of the "to" beacon and specify it as weaviate://localhost/<id>
      })
      .withReference({
        from: `weaviate://localhost/Author/36ddd591-2dee-4e7e-a3cc-eb86d30a4304/wroteArticles`,
        to: `weaviate://localhost/Article/b72912b9-e5d7-304e-a654-66dc63c55b32`,
        // prior to v1.14 omit the class name as part of the "to" beacon and specify it as weaviate://localhost/<id>
      })
      .do()
      .then(res => {
        console.log(res)
      })
      .catch(err => {
          console.error(err)
      });

/* This is also possible with a builder pattern:
const weaviate = require("weaviate-client");

const client = weaviate.client({
  scheme: 'http',
  host: 'localhost:8080',
});

client.batch
      .referencesBatcher()
      .withReference(
        client.batch
          .referencePayloadBuilder()
          .withFromClassName("Author")
          .withFromRefProp('wroteArticles')
          .withFromId("36ddd591-2dee-4e7e-a3cc-eb86d30a4303")
          .withToClassName("Article") // prior to v1.14 omit .withToClassName()
          .withToId("6bb06a43-e7f0-393e-9ecf-3c0f4e129064")
          .payload()
      )
      .withReference(
        client.batch
          .referencePayloadBuilder()
          .withFromClassName("Author")
          .withFromRefProp('wroteArticles')
          .withFromId("36ddd591-2dee-4e7e-a3cc-eb86d30a4303")
          .withToClassName("Article") // prior to v1.14 omit .withToClassName()
          .withToId("b72912b9-e5d7-304e-a654-66dc63c55b32")
          .payload()
      )
      .withReference(
        client.batch
          .referencePayloadBuilder()
          .withFromClassName("Author")
          .withFromRefProp('wroteArticles')
          .withFromId("36ddd591-2dee-4e7e-a3cc-eb86d30a4304")
          .withToClassName("Article") // prior to v1.14 omit .withToClassName()
          .withToId("b72912b9-e5d7-304e-a654-66dc63c55b32")
          .payload()
      )
      .do()
      .then(res => {
        console.log(res)
      })
      .catch(err => {
          console.error(err)
      });
*/
  package main

import (
  "context"
  "fmt"

  "github.com/semi-technologies/weaviate-go-client/v4/weaviate"
  "github.com/semi-technologies/weaviate/entities/models"
)

func main() {
  cfg := weaviate.Config{
    Host:   "localhost:8080",
    Scheme: "http",
  }
  client := weaviate.New(cfg)

  ref := []*models.BatchReference{
    {
      From: "weaviate://localhost/Author/36ddd591-2dee-4e7e-a3cc-eb86d30a4303/wroteArticles",
      To:   "weaviate://localhost/Article/6bb06a43-e7f0-393e-9ecf-3c0f4e129064",
      // prior to v1.14 omit the class name as part of the "to" beacon and specify it as weaviate://localhost/<id>
    },
    {
      From: "weaviate://localhost/Author/36ddd591-2dee-4e7e-a3cc-eb86d30a4303/wroteArticles",
      To:   "weaviate://localhost/Article/b72912b9-e5d7-304e-a654-66dc63c55b32",
      // prior to v1.14 omit the class name as part of the "to" beacon and specify it as weaviate://localhost/<id>
    },
    {
      From: "weaviate://localhost/Author/36ddd591-2dee-4e7e-a3cc-eb86d30a4304/wroteArticles",
      To:   "weaviate://localhost/Article/b72912b9-e5d7-304e-a654-66dc63c55b32",
      // prior to v1.14 omit the class name as part of the "to" beacon and specify it as weaviate://localhost/<id>
    },
  }

  result, err := client.Batch().ReferencesBatcher().
    WithReference(ref[0]).
    WithReference(ref[1]).
    WithReference(ref[2]).
    Do(context.Background())

  if err != nil {
    panic(err)
  }
  fmt.Printf("%v", result)
}
  package technology.semi.weaviate;

import java.util.ArrayList;
import java.util.List;
import technology.semi.weaviate.client.Config;
import technology.semi.weaviate.client.WeaviateClient;
import technology.semi.weaviate.client.base.Result;
import technology.semi.weaviate.client.v1.batch.model.BatchReference;
import technology.semi.weaviate.client.v1.batch.model.BatchReferenceResponse;

public class App {
  public static void main(String[] args) {
    Config config = new Config("http", "localhost:8080");
    WeaviateClient client = new WeaviateClient(config);

    List<BatchReference> refs = new ArrayList() {
      {
        add(
          BatchReference.builder()
            .from("weaviate://localhost/Author/36ddd591-2dee-4e7e-a3cc-eb86d30a4303/wroteArticles")
            .to("weaviate://localhost/Article/6bb06a43-e7f0-393e-9ecf-3c0f4e129064")
            // prior to v1.14 omit the class name as part of the "to" beacon and specify it as weaviate://localhost/<id>
            .build()
        );
        add(
          BatchReference.builder()
            .from("weaviate://localhost/Author/36ddd591-2dee-4e7e-a3cc-eb86d30a4303/wroteArticles")
            .to("weaviate://localhost/Article/b72912b9-e5d7-304e-a654-66dc63c55b32")
            // prior to v1.14 omit the class name as part of the "to" beacon and specify it as weaviate://localhost/<id>
            .build()
        );
        add(
          BatchReference.builder()
            .from("weaviate://localhost/Author/36ddd591-2dee-4e7e-a3cc-eb86d30a4304/wroteArticles")
            .to("weaviate://localhost/Article/b72912b9-e5d7-304e-a654-66dc63c55b32")
            // prior to v1.14 omit the class name as part of the "to" beacon and specify it as weaviate://localhost/<id>
            .build()
        );
      }
    };

    Result<BatchReferenceResponse[]> result = client.batch().referencesBatcher()
      .withReference(refs.get(0))
      .withReference(refs.get(1))
      .withReference(refs.get(2))
      .run();

    if (result.hasErrors()) {
      System.out.println(result.getError());
      return;
    }
    System.out.println(result.getResult());
  }
}
  # Note that for this query to work with Weaviate versions older than v1.14 you
# need to omit the class name in the "to" beacon and specify it as
# weaviate://localhost/<id>. The long-form beacon used in "from" is unchanged.
$ curl \
-X POST \
-H "Content-Type: application/json" \
-d '[{
    "from": "weaviate://localhost/Author/36ddd591-2dee-4e7e-a3cc-eb86d30a4303/wroteArticles",
    "to": "weaviate://localhost/Article/6bb06a43-e7f0-393e-9ecf-3c0f4e129064"
  }, {
    "from": "weaviate://localhost/Author/36ddd591-2dee-4e7e-a3cc-eb86d30a4303/wroteArticles",
    "to": "weaviate://localhost/Article/b72912b9-e5d7-304e-a654-66dc63c55b32"
  }, {
    "from": "weaviate://localhost/Author/36ddd591-2dee-4e7e-a3cc-eb86d30a4304/wroteArticles",
    "to": "weaviate://localhost/Article/b72912b9-e5d7-304e-a654-66dc63c55b32"
  }]' \
http://localhost:8080/v1/batch/references

For detailed information and instructions of batching in Python, click here.

Batch Delete By Query

You can use the /v1/batch/objects endpoint with the HTTP Verb DELETE to delete all objects that match a particular expression. To determine if an object is a match a where-Filter is used. The request body takes a single filter, but will delete all objects matched. It returns the number of matched objects as well as any potential errors. Note that there is a limit to how many objects can be deleted using this filter at once which is explained below.

Maximum number of deletes per query

There is an upper limit to how many objects can be deleted using a single query. This protects against unexpected memory surges and very-long running requests which would be prone to client-side timeouts or network interruptions. If a filter matches many objects, only the first n elements are deleted. You can configure the amount n by setting QUERY_MAXIMUM_RESULTS in Weaviate’s config. The default value is 10,000. Objects are deleted in the same order that they would be returned using the same filter in a a Get-Query. To delete more objects than the limit, run the same query multiple times, until no objects are matched anymore.

Dry-Run before Deletion

You can use the dry-run option to see which objects would be deleted using your specified filter without deleting any objects yet. Depending on the verbosity set, you will either receive the total count of affected objects or a list of the affected IDs.

Method and URL

DELETE /v1/batch/objects

Parameters

The body requires the following field:

nametyperequireddescription
matchobjectyesan object outlining how to find the objects to be deleted, see an example below
outputstringnooptional, controls the verbosity of the output, see possible values below. Defaults to "minimal"
dryRunboolnooptional, if true, objects will not be deleted yet, but merely listed. Defaults to false

A request body in detail

{
  "match": {
    "class": "<ClassName>", # required
    "where": { /* where filter object */ },  # required
  },
  "output": "<output verbosity>" # Optional, one of "minimal", "verbose". Defaults to "minimal"
  "dryRun": <bool> # Optional, if true, objects will not be deleted yet, but merely listed. Defaults to "false"
}

Possible values for output

valueeffect
minimalThe result only includes counts. Information about objects is omitted if the deletes were successful. Only if an error occurred will the object be described.
verboseThe result lists all affected objects with their ID and deletion status, including both successful and unsuccessful deletes

A response body in detail

{
  "match": {
    "class": "<ClassName>",      # matches the request
    "where": { /* where filter object */ },  # matches the request
  },
  "output": "<output verbosity>" # matches the request
  "dryRun": <bool>
  "results": {
    "matches": "<int>"           # how many objects were matched by the filter
    "limit": "<int>"             # the most amount of objects that can be deleted in a single query, matches QUERY_MAXIMUM_RESULTS
    "successful": "<int>"        # how many objects were successfully deleted in this round
    "failed": "<int>"            # how many objects should have been deleted but could not be deleted
    "objects": [{                # one json object per weaviate object
      "id": "<id>",              # This successfully deleted object would be ommitted with output=minimal
      "status": "SUCCESS",       # Possible status values are: "SUCCESS", "FAILED", "DRYRUN"
      "error": null
    }, {
      "id": "<id>",              # This error'd object will always be listed, even with output=minimal
      "status": "FAILED",
      "errors": {
         "error": [{
             "message": "<error-string>"
         }]
      }
    ]}
  }
}

Example request

  import weaviate

client = weaviate.Client('http://localhost:8080')

result = client.batch.delete_objects(
	class_name='Author',
	# same where operator as in the GraphQL API
	where={
		'operator': 'Equal',
		'path': ['name'],
		'valueText': 'Jane'
	},
	output='verbose',
	dry_run=False,
)

print(result)
  const weaviate = require("weaviate-client");

const client = weaviate.client({
	scheme: 'http',
	host: 'localhost:8080',
});

client.batch
	.objectsBatchDeleter()
	.withClassName("Article")
	.withOutput("verbose")
	.withDryRun(false)
	.withWhere({
	  operator: "GreaterThan",
	  path: ["_creationTimeUnix"],
	  valueString: "1651514874263",
	})
	.do()
	.then(console.log)
	.catch(console.error);
  package main

import (
	"context"
	"fmt"

	"github.com/semi-technologies/weaviate-go-client/v4/weaviate"
	"github.com/semi-technologies/weaviate-go-client/v4/weaviate/filters"
)

func main() {
	cfg := weaviate.Config{
		Host:   "localhost:8080",
		Scheme: "http",
	}
	client := weaviate.New(cfg)

	where := filters.Where().
		WithOperator(filters.GreaterThan).
		WithPath([]string{"_creationTimeUnix"}).
		WithValueString("1651514874263")

	result, err := client.Batch().ObjectsBatchDeleter().
		WithClassName("Article").
		WithOutput("verbose").
		WithDryRun(false).
		WithWhere(where).
		Do(context.Background())

	if err != nil {
		panic(err)
	}

	fmt.Printf("%v", result)
}
  package technology.semi.weaviate;

import technology.semi.weaviate.client.Config;
import technology.semi.weaviate.client.WeaviateClient;
import technology.semi.weaviate.client.base.Result;
import technology.semi.weaviate.client.v1.batch.model.BatchDeleteOutput;
import technology.semi.weaviate.client.v1.batch.model.BatchDeleteResponse;
import technology.semi.weaviate.client.v1.filters.Operator;
import technology.semi.weaviate.client.v1.filters.WhereFilter;

public class App {
  public static void main(String[] args) {
    Config config = new Config("http", "localhost:8080");
    WeaviateClient client = new WeaviateClient(config);

    WhereFilter where = WhereFilter.builder()
            .operator(Operator.GreaterThan)
            .path(new String[]{ "_creationTimeUnix" })
            .valueString("1651514874263")
            .build();

    Result<BatchDeleteResponse> result = client.batch().objectsBatchDeleter()
            .withClassName("Article")
            .withOutput(BatchDeleteOutput.VERBOSE)
            .withDryRun(false)
            .withWhere(where)
            .run();

    if (result.hasErrors()) {
      System.out.println(result.getError());
      return;
    }
    System.out.println(result.getResult());
  }
}
  $ curl \
-X DELETE \
-H "Content-Type: application/json" \
-d '{
  "match": {
    "class": "Author",
    "where": {
      "valueText": "Jane",
      "path": ["name"],
      "operator": "Equal"
    }
  },
  "output": "verbose",
  "dryRun": false
}' \
http://localhost:8080/v1/batch/objects

Error handling

When sending a batch request to your Weaviate instance, it could be the case that an error occurs. This can be caused by several reasons, for example that the connection to Weaviate is lost or that there is a mistake in a single data object that you are trying to add.

You can check if an error and what kind has occurred.

A batch request will always return a HTTP 200 status code when a the batch request was successful. That means that the batch was successfully sent to Weaviate, and there were no issues with the connection or processing of the batch and no malformed request (4xx status code). However, with a 200 status code, there might still be individual failures of the data objects which are not contained in the response. Thus, a 200 status code does not guarantee that each batch item is added/created. An example of an error on an individual data object that might be unnoticed by sending a batch request without checking the individual results is: Adding an object to the batch that is in conflict with the schema (for example a non existing class name).

The following Python code can be used to handle errors on individual data objects in the batch.

import weaviate

client = weaviate.Client("http://localhost:8080")


def check_batch_result(results: dict):
  """
  Check batch results for errors.

  Parameters
  ----------
  results : dict
      The Weaviate batch creation return value, i.e. returned value of the client.batch.create_objects().
  """

  if results is not None:
    for result in results:
      if 'result' in result and 'errors' in result['result']:
        if 'error' in result['result']['errors']:
          print(result['result']['errors']['error'])

object_to_add = {
    "name": "Jane Doe",
    "writesFor": [{
        "beacon": "weaviate://localhost/f81bfe5e-16ba-4615-a516-46c2ae2e5a80"
    }]
}

with client.batch(batch_size=100, callback=check_batch_result) as batch:
  batch.add_data_object(object_to_add, "Author", "36ddd591-2dee-4e7e-a3cc-eb86d30a4303")

This can also be applied to adding references in batch. Note that sending batches, especially references, skips some validation on object and reference level. Adding this validation on single data objects like above makes it less likely for errors to pass without discovering.

More Resources

If you can’t find the answer to your question here, please look at the:

  1. Frequently Asked Questions. Or,
  2. Knowledge base of old issues. Or,
  3. For questions: Stackoverflow. Or,
  4. For issues: Github. Or,
  5. Ask your question in the Slack channel: Slack.