Skip to content

Commit 3994181

Browse files
authored
Merge pull request #1775 from meilisearch/feat/add-batch-routes
Add batch routes
2 parents dfe5be8 + f05a5b8 commit 3994181

File tree

7 files changed

+237
-0
lines changed

7 files changed

+237
-0
lines changed

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,20 @@ client.waitForTasks(uids: number[], { timeOutMs?: number, intervalMs?: number })
565565
client.index('myIndex').waitForTasks(uids: number[], { timeOutMs?: number, intervalMs?: number }): Promise<Task[]>
566566
```
567567

568+
### Batches <!-- omit in toc -->
569+
570+
#### [Get one batch](https://www.meilisearch.com/docs/reference/api/batches#get-one-batch)
571+
572+
```ts
573+
client.getBatch(uid: number): Promise<Batch>
574+
```
575+
576+
#### [Get all batches](https://www.meilisearch.com/docs/reference/api/batchess#get-batches)
577+
578+
```ts
579+
client.getBatches(parameters: BatchesQuery = {}): Promise<BatchesResults>
580+
```
581+
568582
### Indexes <!-- omit in toc -->
569583

570584
#### [Get all indexes in Index instances](https://www.meilisearch.com/docs/reference/api/indexes#list-all-indexes)

src/batch.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import {
2+
Config,
3+
BatchObject,
4+
BatchesQuery,
5+
BatchesResults,
6+
BatchesResultsObject,
7+
} from "./types";
8+
import { HttpRequests, toQueryParams } from "./http-requests";
9+
10+
class Batch {
11+
uid: BatchObject["uid"];
12+
details: BatchObject["details"];
13+
stats: BatchObject["stats"];
14+
startedAt: BatchObject["startedAt"];
15+
finishedAt: BatchObject["finishedAt"];
16+
duration: BatchObject["duration"];
17+
18+
constructor(batch: BatchObject) {
19+
this.uid = batch.uid;
20+
this.details = batch.details;
21+
this.stats = batch.stats;
22+
this.startedAt = batch.startedAt;
23+
this.finishedAt = batch.finishedAt;
24+
this.duration = batch.duration;
25+
}
26+
}
27+
28+
class BatchClient {
29+
httpRequest: HttpRequests;
30+
31+
constructor(config: Config) {
32+
this.httpRequest = new HttpRequests(config);
33+
}
34+
35+
/**
36+
* Get one batch
37+
*
38+
* @param uid - Unique identifier of the batch
39+
* @returns
40+
*/
41+
async getBatch(uid: number): Promise<Batch> {
42+
const url = `batches/${uid}`;
43+
const batch = await this.httpRequest.get<BatchObject>(url);
44+
return new Batch(batch);
45+
}
46+
47+
/**
48+
* Get batches
49+
*
50+
* @param parameters - Parameters to browse the batches
51+
* @returns Promise containing all batches
52+
*/
53+
async getBatches(parameters: BatchesQuery = {}): Promise<BatchesResults> {
54+
const url = `batches`;
55+
56+
const batches = await this.httpRequest.get<Promise<BatchesResultsObject>>(
57+
url,
58+
toQueryParams<BatchesQuery>(parameters),
59+
);
60+
61+
return {
62+
...batches,
63+
results: batches.results.map((batch) => new Batch(batch)),
64+
};
65+
}
66+
}
67+
68+
export { BatchClient, Batch };

src/meilisearch.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,20 @@ import {
3030
DeleteTasksQuery,
3131
MultiSearchParams,
3232
FederatedMultiSearchParams,
33+
BatchesResults,
34+
BatchesQuery,
3335
MultiSearchResponseOrSearchResponse,
3436
} from "./types";
3537
import { HttpRequests } from "./http-requests";
3638
import { TaskClient, Task } from "./task";
3739
import { EnqueuedTask } from "./enqueued-task";
40+
import { Batch, BatchClient } from "./batch";
3841

3942
export class MeiliSearch {
4043
config: Config;
4144
httpRequest: HttpRequests;
4245
tasks: TaskClient;
46+
batches: BatchClient;
4347

4448
/**
4549
* Creates new MeiliSearch instance
@@ -50,6 +54,7 @@ export class MeiliSearch {
5054
this.config = config;
5155
this.httpRequest = new HttpRequests(config);
5256
this.tasks = new TaskClient(config);
57+
this.batches = new BatchClient(config);
5358
}
5459

5560
/**
@@ -303,6 +308,26 @@ export class MeiliSearch {
303308
return await this.tasks.deleteTasks(parameters);
304309
}
305310

311+
/**
312+
* Get all the batches
313+
*
314+
* @param parameters - Parameters to browse the batches
315+
* @returns Promise returning all batches
316+
*/
317+
async getBatches(parameters: BatchesQuery = {}): Promise<BatchesResults> {
318+
return await this.batches.getBatches(parameters);
319+
}
320+
321+
/**
322+
* Get one batch
323+
*
324+
* @param uid - Batch identifier
325+
* @returns Promise returning a batch
326+
*/
327+
async getBatch(uid: number): Promise<Batch> {
328+
return await this.batches.getBatch(uid);
329+
}
330+
306331
///
307332
/// KEYS
308333
///

src/task.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class Task {
1919
status: TaskObject["status"];
2020
type: TaskObject["type"];
2121
uid: TaskObject["uid"];
22+
batchUid: TaskObject["batchUid"];
2223
canceledBy: TaskObject["canceledBy"];
2324
details: TaskObject["details"];
2425
error: TaskObject["error"];
@@ -32,6 +33,7 @@ class Task {
3233
this.status = task.status;
3334
this.type = task.type;
3435
this.uid = task.uid;
36+
this.batchUid = task.batchUid;
3537
this.details = task.details;
3638
this.canceledBy = task.canceledBy;
3739
this.error = task.error;

src/types/types.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// TypeScript Version: ^3.8.3
66

77
import { Task } from "../task";
8+
import { Batch } from "../batch";
89

910
export type Config = {
1011
host: string;
@@ -578,6 +579,8 @@ export type EnqueuedTaskObject = {
578579

579580
export type TaskObject = Omit<EnqueuedTaskObject, "taskUid"> & {
580581
uid: number;
582+
/** The UID of the batch that the task belongs to (`null` for enqueued tasks) */
583+
batchUid: number | null;
581584
details: {
582585
// Number of documents sent
583586
receivedDocuments?: number;
@@ -659,6 +662,83 @@ export type WaitOptions = {
659662
intervalMs?: number;
660663
};
661664

665+
/*
666+
** BATCHES
667+
*/
668+
669+
/**
670+
* Represents a batch operation object containing information about tasks
671+
* processing
672+
*/
673+
export type BatchObject = {
674+
/** Unique identifier for the batch */
675+
uid: number;
676+
677+
/** Details about document processing */
678+
details: {
679+
/** Number of documents received in the batch */
680+
receivedDocuments?: number;
681+
/** Number of documents successfully indexed */
682+
indexedDocuments?: number;
683+
/** Number of documents deleted in the batch */
684+
deletedDocuments?: number;
685+
};
686+
687+
/** Progress indicator (currently always null) */
688+
progress: null;
689+
690+
/** Statistics about tasks within the batch */
691+
stats: {
692+
/** Total number of tasks in the batch */
693+
totalNbTasks: number;
694+
/** Count of tasks in each status */
695+
status: {
696+
/** Number of successfully completed tasks */
697+
succeeded: number;
698+
/** Number of failed tasks */
699+
failed: number;
700+
/** Number of canceled tasks */
701+
canceled: number;
702+
/** Number of tasks currently processing */
703+
processing: number;
704+
/** Number of tasks waiting to be processed */
705+
enqueued: number;
706+
};
707+
/** Count of tasks by type */
708+
types: Record<TaskTypes, number>;
709+
/** Count of tasks by index UID */
710+
indexUids: Record<string, number>;
711+
};
712+
713+
/** Timestamp when the batch started processing (rfc3339 format) */
714+
startedAt: string;
715+
/** Timestamp when the batch finished processing (rfc3339 format) */
716+
finishedAt: string;
717+
/** Duration of batch processing */
718+
duration: string;
719+
};
720+
721+
export type BatchesQuery = {
722+
/** The batch should contain the specified task UIDs */
723+
uids?: number[];
724+
batchUids?: number[];
725+
types?: TaskTypes[];
726+
statuses?: TaskStatus[];
727+
indexUids?: string[];
728+
canceledBy?: number[];
729+
beforeEnqueuedAt?: Date;
730+
afterEnqueuedAt?: Date;
731+
beforeStartedAt?: Date;
732+
afterStartedAt?: Date;
733+
beforeFinishedAt?: Date;
734+
afterFinishedAt?: Date;
735+
limit?: number;
736+
from?: number;
737+
};
738+
739+
export type BatchesResults = CursorResults<Batch>;
740+
export type BatchesResultsObject = CursorResults<BatchObject>;
741+
662742
/*
663743
*** HEALTH
664744
*/

tests/batch.test.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { afterAll, beforeEach, describe, expect, test } from "vitest";
2+
import {
3+
config,
4+
getClient,
5+
clearAllIndexes,
6+
} from "./utils/meilisearch-test-utils";
7+
8+
const index = {
9+
uid: "batch-test",
10+
};
11+
12+
afterAll(() => {
13+
return clearAllIndexes(config);
14+
});
15+
16+
describe.each([{ permission: "Master" }, { permission: "Admin" }])(
17+
"Tests on batches",
18+
({ permission }) => {
19+
beforeEach(async () => {
20+
const client = await getClient("Master");
21+
const { taskUid } = await client.createIndex(index.uid);
22+
await client.waitForTask(taskUid);
23+
});
24+
25+
test(`${permission} key: Get all batches`, async () => {
26+
const client = await getClient(permission);
27+
const batches = await client.getBatches();
28+
expect(batches.results.length).toBeGreaterThan(0);
29+
});
30+
31+
test(`${permission} key: Get one batch`, async () => {
32+
const client = await getClient(permission);
33+
34+
const batches = await client.getBatches();
35+
const batch = await client.getBatch(batches.results[0].uid);
36+
expect(batch.uid).toEqual(batches.results[0].uid);
37+
expect(batch.details).toBeDefined();
38+
expect(batch.stats).toHaveProperty("totalNbTasks");
39+
expect(batch.stats).toHaveProperty("status");
40+
expect(batch.stats).toHaveProperty("types");
41+
expect(batch.stats).toHaveProperty("indexUids");
42+
expect(batch.duration).toBeDefined();
43+
expect(batch.startedAt).toBeDefined();
44+
expect(batch.finishedAt).toBeDefined();
45+
});
46+
},
47+
);

tests/task.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])(
5656
const task = await client.getTask(enqueuedTask.taskUid);
5757

5858
expect(task.indexUid).toEqual(index.uid);
59+
expect(task.batchUid).toBeDefined();
5960
expect(task.status).toEqual(TaskStatus.TASK_SUCCEEDED);
6061
expect(task.type).toEqual(TaskTypes.DOCUMENTS_ADDITION_OR_UPDATE);
6162
expect(task.uid).toEqual(enqueuedTask.taskUid);

0 commit comments

Comments
 (0)