Skip to content

Commit

Permalink
Merge pull request #1775 from meilisearch/feat/add-batch-routes
Browse files Browse the repository at this point in the history
Add batch routes
  • Loading branch information
Strift authored Dec 10, 2024
2 parents dfe5be8 + f05a5b8 commit 3994181
Show file tree
Hide file tree
Showing 7 changed files with 237 additions and 0 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,20 @@ client.waitForTasks(uids: number[], { timeOutMs?: number, intervalMs?: number })
client.index('myIndex').waitForTasks(uids: number[], { timeOutMs?: number, intervalMs?: number }): Promise<Task[]>
```

### Batches <!-- omit in toc -->

#### [Get one batch](https://www.meilisearch.com/docs/reference/api/batches#get-one-batch)

```ts
client.getBatch(uid: number): Promise<Batch>
```

#### [Get all batches](https://www.meilisearch.com/docs/reference/api/batchess#get-batches)

```ts
client.getBatches(parameters: BatchesQuery = {}): Promise<BatchesResults>
```

### Indexes <!-- omit in toc -->

#### [Get all indexes in Index instances](https://www.meilisearch.com/docs/reference/api/indexes#list-all-indexes)
Expand Down
68 changes: 68 additions & 0 deletions src/batch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import {
Config,
BatchObject,
BatchesQuery,
BatchesResults,
BatchesResultsObject,
} from "./types";
import { HttpRequests, toQueryParams } from "./http-requests";

class Batch {
uid: BatchObject["uid"];
details: BatchObject["details"];
stats: BatchObject["stats"];
startedAt: BatchObject["startedAt"];
finishedAt: BatchObject["finishedAt"];
duration: BatchObject["duration"];

constructor(batch: BatchObject) {
this.uid = batch.uid;
this.details = batch.details;
this.stats = batch.stats;
this.startedAt = batch.startedAt;
this.finishedAt = batch.finishedAt;
this.duration = batch.duration;
}
}

class BatchClient {
httpRequest: HttpRequests;

constructor(config: Config) {
this.httpRequest = new HttpRequests(config);
}

/**
* Get one batch
*
* @param uid - Unique identifier of the batch
* @returns
*/
async getBatch(uid: number): Promise<Batch> {
const url = `batches/${uid}`;
const batch = await this.httpRequest.get<BatchObject>(url);
return new Batch(batch);
}

/**
* Get batches
*
* @param parameters - Parameters to browse the batches
* @returns Promise containing all batches
*/
async getBatches(parameters: BatchesQuery = {}): Promise<BatchesResults> {
const url = `batches`;

const batches = await this.httpRequest.get<Promise<BatchesResultsObject>>(
url,
toQueryParams<BatchesQuery>(parameters),
);

return {
...batches,
results: batches.results.map((batch) => new Batch(batch)),
};
}
}

export { BatchClient, Batch };
25 changes: 25 additions & 0 deletions src/meilisearch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,20 @@ import {
DeleteTasksQuery,
MultiSearchParams,
FederatedMultiSearchParams,
BatchesResults,
BatchesQuery,
MultiSearchResponseOrSearchResponse,
} from "./types";
import { HttpRequests } from "./http-requests";
import { TaskClient, Task } from "./task";
import { EnqueuedTask } from "./enqueued-task";
import { Batch, BatchClient } from "./batch";

export class MeiliSearch {
config: Config;
httpRequest: HttpRequests;
tasks: TaskClient;
batches: BatchClient;

/**
* Creates new MeiliSearch instance
Expand All @@ -50,6 +54,7 @@ export class MeiliSearch {
this.config = config;
this.httpRequest = new HttpRequests(config);
this.tasks = new TaskClient(config);
this.batches = new BatchClient(config);
}

/**
Expand Down Expand Up @@ -303,6 +308,26 @@ export class MeiliSearch {
return await this.tasks.deleteTasks(parameters);
}

/**
* Get all the batches
*
* @param parameters - Parameters to browse the batches
* @returns Promise returning all batches
*/
async getBatches(parameters: BatchesQuery = {}): Promise<BatchesResults> {
return await this.batches.getBatches(parameters);
}

/**
* Get one batch
*
* @param uid - Batch identifier
* @returns Promise returning a batch
*/
async getBatch(uid: number): Promise<Batch> {
return await this.batches.getBatch(uid);
}

///
/// KEYS
///
Expand Down
2 changes: 2 additions & 0 deletions src/task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class Task {
status: TaskObject["status"];
type: TaskObject["type"];
uid: TaskObject["uid"];
batchUid: TaskObject["batchUid"];
canceledBy: TaskObject["canceledBy"];
details: TaskObject["details"];
error: TaskObject["error"];
Expand All @@ -32,6 +33,7 @@ class Task {
this.status = task.status;
this.type = task.type;
this.uid = task.uid;
this.batchUid = task.batchUid;
this.details = task.details;
this.canceledBy = task.canceledBy;
this.error = task.error;
Expand Down
80 changes: 80 additions & 0 deletions src/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// TypeScript Version: ^3.8.3

import { Task } from "../task";
import { Batch } from "../batch";

export type Config = {
host: string;
Expand Down Expand Up @@ -578,6 +579,8 @@ export type EnqueuedTaskObject = {

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

/*
** BATCHES
*/

/**
* Represents a batch operation object containing information about tasks
* processing
*/
export type BatchObject = {
/** Unique identifier for the batch */
uid: number;

/** Details about document processing */
details: {
/** Number of documents received in the batch */
receivedDocuments?: number;
/** Number of documents successfully indexed */
indexedDocuments?: number;
/** Number of documents deleted in the batch */
deletedDocuments?: number;
};

/** Progress indicator (currently always null) */
progress: null;

/** Statistics about tasks within the batch */
stats: {
/** Total number of tasks in the batch */
totalNbTasks: number;
/** Count of tasks in each status */
status: {
/** Number of successfully completed tasks */
succeeded: number;
/** Number of failed tasks */
failed: number;
/** Number of canceled tasks */
canceled: number;
/** Number of tasks currently processing */
processing: number;
/** Number of tasks waiting to be processed */
enqueued: number;
};
/** Count of tasks by type */
types: Record<TaskTypes, number>;
/** Count of tasks by index UID */
indexUids: Record<string, number>;
};

/** Timestamp when the batch started processing (rfc3339 format) */
startedAt: string;
/** Timestamp when the batch finished processing (rfc3339 format) */
finishedAt: string;
/** Duration of batch processing */
duration: string;
};

export type BatchesQuery = {
/** The batch should contain the specified task UIDs */
uids?: number[];
batchUids?: number[];
types?: TaskTypes[];
statuses?: TaskStatus[];
indexUids?: string[];
canceledBy?: number[];
beforeEnqueuedAt?: Date;
afterEnqueuedAt?: Date;
beforeStartedAt?: Date;
afterStartedAt?: Date;
beforeFinishedAt?: Date;
afterFinishedAt?: Date;
limit?: number;
from?: number;
};

export type BatchesResults = CursorResults<Batch>;
export type BatchesResultsObject = CursorResults<BatchObject>;

/*
*** HEALTH
*/
Expand Down
47 changes: 47 additions & 0 deletions tests/batch.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { afterAll, beforeEach, describe, expect, test } from "vitest";
import {
config,
getClient,
clearAllIndexes,
} from "./utils/meilisearch-test-utils";

const index = {
uid: "batch-test",
};

afterAll(() => {
return clearAllIndexes(config);
});

describe.each([{ permission: "Master" }, { permission: "Admin" }])(
"Tests on batches",
({ permission }) => {
beforeEach(async () => {
const client = await getClient("Master");
const { taskUid } = await client.createIndex(index.uid);
await client.waitForTask(taskUid);
});

test(`${permission} key: Get all batches`, async () => {
const client = await getClient(permission);
const batches = await client.getBatches();
expect(batches.results.length).toBeGreaterThan(0);
});

test(`${permission} key: Get one batch`, async () => {
const client = await getClient(permission);

const batches = await client.getBatches();
const batch = await client.getBatch(batches.results[0].uid);
expect(batch.uid).toEqual(batches.results[0].uid);
expect(batch.details).toBeDefined();
expect(batch.stats).toHaveProperty("totalNbTasks");
expect(batch.stats).toHaveProperty("status");
expect(batch.stats).toHaveProperty("types");
expect(batch.stats).toHaveProperty("indexUids");
expect(batch.duration).toBeDefined();
expect(batch.startedAt).toBeDefined();
expect(batch.finishedAt).toBeDefined();
});
},
);
1 change: 1 addition & 0 deletions tests/task.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])(
const task = await client.getTask(enqueuedTask.taskUid);

expect(task.indexUid).toEqual(index.uid);
expect(task.batchUid).toBeDefined();
expect(task.status).toEqual(TaskStatus.TASK_SUCCEEDED);
expect(task.type).toEqual(TaskTypes.DOCUMENTS_ADDITION_OR_UPDATE);
expect(task.uid).toEqual(enqueuedTask.taskUid);
Expand Down

0 comments on commit 3994181

Please sign in to comment.