Skip to content

Commit 84b2d7f

Browse files
authored
Merge pull request #466 from weaviate/docs/server-side-batching-snippets
docs: make server-side batching the default import method
2 parents 7140f00 + d90552a commit 84b2d7f

7 files changed

Lines changed: 152 additions & 71 deletions

File tree

.github/workflows/docs_tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ jobs:
456456

457457
- name: Clone and build Java client SNAPSHOT
458458
run: |
459-
JAVA_BRANCH="${{ inputs.java_client_branch || '6.2.0' }}"
459+
JAVA_BRANCH="${{ inputs.java_client_branch || '6.3.0' }}"
460460
echo "📦 Building Java client SNAPSHOT from branch: $JAVA_BRANCH"
461461
git clone --depth 1 -b "$JAVA_BRANCH" https://github.com/weaviate/java-client.git /tmp/java-client
462462
cd /tmp/java-client

_includes/code/csharp/ManageObjectsImportTest.cs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,43 @@ await client.Collections.Create(
126126
Assert.Equal(5, result.TotalCount);
127127
}
128128

129-
// START ServerSideBatchImportExample
130-
// Coming soon
131-
// END ServerSideBatchImportExample
129+
[Fact]
130+
public async Task TestServerSideBatchImport()
131+
{
132+
await BeforeEach();
133+
await client.Collections.Create(
134+
new CollectionCreateParams
135+
{
136+
Name = "MyCollection",
137+
VectorConfig = Configure.Vector("default", v => v.SelfProvided()),
138+
}
139+
);
140+
141+
// START ServerSideBatchImportExample
142+
var dataRows = Enumerable
143+
.Range(0, 5)
144+
.Select(i => new { title = $"Object {i + 1}" })
145+
.ToList();
146+
147+
var collection = client.Collections.Use("MyCollection");
148+
149+
// Use `Batch.InsertMany` for server-side batching. The client sends
150+
// data in batches at a rate controlled by the server.
151+
// highlight-start
152+
var response = await collection.Batch.InsertMany(dataRows);
153+
// highlight-end
154+
155+
var failedObjects = response.Where(r => r.Error != null).ToList();
156+
if (failedObjects.Any())
157+
{
158+
Console.WriteLine($"Number of failed imports: {failedObjects.Count}");
159+
Console.WriteLine($"First failed object: {failedObjects.First().Error}");
160+
}
161+
// END ServerSideBatchImportExample
162+
163+
var result = await collection.Aggregate.OverAll(totalCount: true);
164+
Assert.Equal(5, result.TotalCount);
165+
}
132166

133167
[Fact]
134168
public async Task TestBatchImportWithID()

_includes/code/howto/manage-data.import.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ console.log(`Finished importing ${counter} articles.`);
319319
// ==================================================
320320
// ===== Server-side (automatic) batch import =====
321321
// ==================================================
322-
/*
322+
323323
// Clean slate
324324
try {
325325
await client.collections.delete('MyCollection');
@@ -335,11 +335,11 @@ try {
335335
{
336336
// START ServerSideBatchImportExample
337337
const dataObjects = [
338-
{ title: 'Object 1' },
339-
{ title: 'Object 2' },
340-
{ title: 'Object 3' },
341-
{ title: 'Object 4' },
342-
{ title: 'Object 5' },
338+
{ properties: { title: 'Object 1' } },
339+
{ properties: { title: 'Object 2' } },
340+
{ properties: { title: 'Object 3' } },
341+
{ properties: { title: 'Object 4' } },
342+
{ properties: { title: 'Object 5' } },
343343
]
344344

345345
const myCollection = client.collections.use('MyCollection')
@@ -352,10 +352,18 @@ const result = await myCollection.data.ingest(dataObjects)
352352

353353
console.log(result)
354354
// END ServerSideBatchImportExample
355+
356+
// Verify the import (not shown in the docs snippet): all 5 objects and
357+
// their `title` property must have persisted.
358+
const check = await myCollection.query.fetchObjects({ limit: 5 })
359+
if (check.objects.length !== 5)
360+
throw new Error(`SSB import: expected 5 objects, got ${check.objects.length}`)
361+
if (!check.objects.every((o) => typeof o.properties.title === 'string' && o.properties.title.length > 0))
362+
throw new Error('SSB import did not persist the title property')
355363
}
356364

357365
await client.collections.delete('MyCollection');
358-
*/
366+
359367
// ===========================
360368
// ===== Batch with gRPC =====
361369
// ===========================

_includes/code/java-v6/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
<dependency>
3131
<groupId>io.weaviate</groupId>
3232
<artifactId>client6</artifactId>
33-
<version>6.2.1-SNAPSHOT</version>
33+
<version>6.3.0</version>
3434
</dependency>
3535

3636
<!-- JUnit 5 for testing -->

_includes/code/java-v6/src/test/java/ManageObjectsImportTest.java

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import io.weaviate.client6.v1.api.collections.Property;
44
import io.weaviate.client6.v1.api.collections.ReferenceProperty;
55
import io.weaviate.client6.v1.api.collections.VectorConfig;
6+
import io.weaviate.client6.v1.api.collections.batch.BatchContext;
67
import io.weaviate.client6.v1.api.collections.data.BatchReference;
78
import io.weaviate.client6.v1.api.collections.Vectors;
89
import io.weaviate.client6.v1.api.collections.WeaviateObject;
@@ -108,11 +109,47 @@ void testBasicBatchImport() throws IOException {
108109
client.collections.delete("MyCollection");
109110
}
110111

111-
//@Test
112+
@Test
112113
void testServerSideBatchImport() throws IOException {
114+
// Define and create the class
115+
client.collections.create("MyCollection",
116+
col -> col.vectorConfig(VectorConfig.selfProvided()));
117+
113118
// START ServerSideBatchImportExample
114-
// Coming soon
119+
List<Map<String, Object>> dataRows = new ArrayList<>();
120+
for (int i = 0; i < 5; i++) {
121+
dataRows.add(Map.of("title", "Object " + (i + 1)));
122+
}
123+
124+
var collection = client.collections.use("MyCollection");
125+
126+
// Use `batch.start()` for server-side batching. The client sends data
127+
// in batches at a rate controlled by the server. The batch is flushed
128+
// and closed automatically when the try-with-resources block exits.
129+
// highlight-start
130+
BatchContext<Map<String, Object>> batch = collection.batch.start();
131+
try (batch) {
132+
for (Map<String, Object> dataRow : dataRows) {
133+
batch.add(WeaviateObject.<Map<String, Object>>of(
134+
obj -> obj.properties(dataRow)));
135+
}
136+
} catch (InterruptedException e) {
137+
Thread.currentThread().interrupt();
138+
}
139+
// highlight-end
140+
141+
// numberOfErrors() reports objects that could not be imported.
142+
if (batch.numberOfErrors() > 0) {
143+
System.err
144+
.println("Number of failed imports: " + batch.numberOfErrors());
145+
}
115146
// END ServerSideBatchImportExample
147+
148+
var result =
149+
collection.aggregate.overAll(agg -> agg.includeTotalCount(true));
150+
assertThat(result.totalCount()).isEqualTo(5);
151+
152+
client.collections.delete("MyCollection");
116153
}
117154

118155
@Test

docs/weaviate/concepts/data-import.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Weaviate offers two flexible methods for importing data in bulk: **client-side b
1919

2020
:::tip
2121

22-
For **code examples**, check out the [How-to: Batch import](../manage-objects/import.mdx) guide. Currently, only the Python client supports server-side batch imports.
22+
For **code examples**, check out the [How-to: Batch import](../manage-objects/import.mdx) guide. Server-side batch imports are supported by the Python, TypeScript, Java, and C# clients. The Go client does not yet support them; use client-side batching instead.
2323

2424
:::
2525

@@ -40,7 +40,7 @@ Weaviate's server-side batching, also known as **automatic batching**, aims to p
4040
When an automatic batch import is initiated, the client opens a persistent connection to the server for the duration of the batch job.
4141

4242
- **Client sends data**: Your client sends objects to the server in chunks, at a rate that is based on server-provided feedback.
43-
- **Server manages queues**: The server places incoming objects into an internal. The queue is decoupled the network communication from the actual database ingestion (like vectorization and storage).
43+
- **Server manages queues**: The server places incoming objects into an internal queue. This queue decouples the network communication from the actual database ingestion (like vectorization and storage).
4444
- **Dynamic backpressure**: The server continuously monitors its internal queue size. It calculates an exponential moving average (EMA) of its workload and tells the client the ideal number of objects to send in the next chunk. This feedback loop allows the system to self-regulate, maximizing throughput without overwhelming the server.
4545
- **Asynchronous errors**: If an error occurs while processing an object (e.g., validation fails), the server sends the error message back to the client over a separate, dedicated stream without interrupting the flow of objects.
4646

docs/weaviate/manage-objects/import.mdx

Lines changed: 57 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,73 @@ import CSharpCode from '!!raw-loader!/_includes/code/csharp/ManageObjectsImportT
1717
import GoCode from '!!raw-loader!/_includes/code/howto/go/docs/manage-data.import_test.go';
1818
import SkipLink from '/src/components/SkipValidationLink'
1919

20-
[Batch imports](../tutorials/import.mdx) are an efficient way to add multiple data objects and cross-references.
20+
[Batch imports](../tutorials/import.mdx) are an efficient way to add multiple data objects and cross-references. For most use cases, we recommend **server-side batching** as the starting point: the server tells the client how much data to send next, so you don't have to tune batch parameters yourself. When you need manual control over the batch size and concurrency — or you are using a client that does not yet support server-side batching — use [manual batching](#manual-batching) instead.
21+
22+
## Server-side batching
23+
24+
import SsbStatus from '/_includes/feature-notes/ssb-status.mdx';
25+
26+
<SsbStatus/>
27+
28+
With [server-side batch imports](../concepts/data-import.mdx#server-side-batching) (also called "automatic" batching), the client sends data in batch sizes determined by feedback from the server. This simplifies your code and helps the server manage its own load. The following example adds objects to a collection named `MyCollection`.
29+
30+
Server-side batching uses the [gRPC API](#use-the-grpc-api), which current client versions enable by default.
31+
32+
<Tabs className="code" groupId="languages">
33+
<TabItem value="py" label="Python">
34+
<FilteredTextBlock
35+
text={PyCode}
36+
startMarker="# START ServerSideBatchImportExample"
37+
endMarker="# END ServerSideBatchImportExample"
38+
language="py"
39+
/>
40+
</TabItem>
41+
<TabItem value="ts" label="JavaScript/TypeScript">
42+
<FilteredTextBlock
43+
text={TSCode}
44+
startMarker="// START ServerSideBatchImportExample"
45+
endMarker="// END ServerSideBatchImportExample"
46+
language="ts"
47+
/>
48+
</TabItem>
49+
<TabItem value="go" label="Go">
50+
51+
The Go client does not support server-side batching; use [manual batching](#manual-batching) instead.
52+
53+
</TabItem>
54+
<TabItem value="java" label="Java">
55+
<FilteredTextBlock
56+
text={JavaV6Code}
57+
startMarker="// START ServerSideBatchImportExample"
58+
endMarker="// END ServerSideBatchImportExample"
59+
language="java"
60+
/>
61+
</TabItem>
62+
<TabItem value="csharp" label="C#">
63+
<FilteredTextBlock
64+
text={CSharpCode}
65+
startMarker="// START ServerSideBatchImportExample"
66+
endMarker="// END ServerSideBatchImportExample"
67+
language="csharp"
68+
/>
69+
</TabItem>
70+
</Tabs>
71+
72+
## Manual batching
73+
74+
Use manual (client-side) batching when you want to control the batch size and concurrency yourself, or when using a client that does not yet support server-side batching (such as the Go client). The following example adds objects to the `MyCollection` collection.
2175

2276
<details>
2377
<summary>Additional information</summary>
2478

25-
To create a bulk import job, follow these steps:
79+
To create a bulk import job manually, follow these steps:
2680

2781
1. Initialize a batch object.
2882
1. Add items to the batch object.
2983
1. Ensure that the last batch is sent (flushed).
3084

3185
</details>
3286

33-
## Basic import
34-
35-
The following example adds objects to the `MyCollection` collection.
36-
3787
<Tabs className="code" groupId="languages">
3888
<TabItem value="py" label="Python">
3989
<FilteredTextBlock
@@ -88,54 +138,6 @@ Find out more about error handling on the Python client [reference page](/weavia
88138
</TabItem>
89139
</Tabs>
90140

91-
## Server-side batching
92-
93-
import SsbStatus from '/_includes/feature-notes/ssb-status.mdx';
94-
95-
<SsbStatus/>
96-
97-
Here's how to import objects into a collection named `MyCollection` using [server-side batch imports](../concepts/data-import.mdx#server-side-batching). The client will send data in batch sizes using feedback from the server.
98-
99-
<Tabs className="code" groupId="languages">
100-
<TabItem value="py" label="Python">
101-
<FilteredTextBlock
102-
text={PyCode}
103-
startMarker="# START ServerSideBatchImportExample"
104-
endMarker="# END ServerSideBatchImportExample"
105-
language="py"
106-
/>
107-
</TabItem>
108-
<TabItem value="ts" label="JavaScript/TypeScript">
109-
110-
```typescript
111-
// TypeScript support coming soon
112-
```
113-
114-
</TabItem>
115-
<TabItem value="go" label="Go">
116-
117-
```go
118-
// Go support coming soon
119-
```
120-
121-
</TabItem>
122-
<TabItem value="java" label="Java">
123-
124-
```java
125-
// Java support coming soon
126-
```
127-
128-
</TabItem>
129-
<TabItem value="csharp" label="C#">
130-
<FilteredTextBlock
131-
text={CSharpCode}
132-
startMarker="// START ServerSideBatchImportExample"
133-
endMarker="// END ServerSideBatchImportExample"
134-
language="csharp"
135-
/>
136-
</TabItem>
137-
</Tabs>
138-
139141
## Use the gRPC API
140142

141143
The [gRPC API](../api/index.mdx) is faster than the REST API. Use the gRPC API to improve import speeds.
@@ -169,7 +171,7 @@ The Java client v6 uses gRPC by default.
169171

170172
To use the gRPC API with the Go client, add the `GrpcConfig` field to your client connection code. Update `Secured` if you use an encrypted connection.<br/><br/>
171173

172-
```java
174+
```go
173175
cfg := weaviate.Config{
174176
Host: fmt.Sprintf("localhost:%v", "8080"),
175177
Scheme: "http",

0 commit comments

Comments
 (0)