From abb587dae4030f5e6954723a584b9b9a18aace4d Mon Sep 17 00:00:00 2001 From: Morgane Dubus Date: Thu, 4 Jan 2024 15:38:45 +0100 Subject: [PATCH 1/2] feat: add proximity precision settings --- README.md | 38 ++++-- src/indexes.ts | 47 +++++++- src/types/types.ts | 2 + tests/__snapshots__/settings.test.ts.snap | 18 +++ tests/proximity_precision.test.ts | 134 ++++++++++++++++++++++ tests/settings.test.ts | 1 + 6 files changed, 230 insertions(+), 10 deletions(-) create mode 100644 tests/proximity_precision.test.ts diff --git a/README.md b/README.md index 7bab077d5..af0bf44b5 100644 --- a/README.md +++ b/README.md @@ -903,19 +903,19 @@ client.index('myIndex').resetTypoTolerance(): Promise ### Separator tokens -#### Get separator tokens +#### [Get separator tokens](https://www.meilisearch.com/docs/reference/api/settings#get-separator-tokens) ```ts client.index('myIndex').getSeparatorTokens(): Promise ``` -#### Update separator tokens +#### [Update separator tokens](https://www.meilisearch.com/docs/reference/api/settings#update-separator-tokens) ```ts client.index('myIndex').updateSeparatorTokens(separatorTokens: SeparatorTokens | null): Promise ``` -#### Reset separator tokens +#### [Reset separator tokens](https://www.meilisearch.com/docs/reference/api/settings#reset-separator-tokens) ```ts client.index('myIndex').resetSeparatorTokens(): Promise @@ -923,19 +923,19 @@ client.index('myIndex').resetSeparatorTokens(): Promise ### Non Separator tokens -#### Get non separator tokens +#### [Get non separator tokens](https://www.meilisearch.com/docs/reference/api/settings#get-non-separator-tokens) ```ts client.index('myIndex').getNonSeparatorTokens(): Promise ``` -#### Update non separator tokens +#### [Update non separator tokens](https://www.meilisearch.com/docs/reference/api/settings#update-non-separator-tokens) ```ts client.index('myIndex').updateNonSeparatorTokens(nonSeparatorTokens: NonSeparatorTokens | null): Promise ``` -#### Reset non separator tokens +#### [Reset non separator tokens](https://www.meilisearch.com/docs/reference/api/settings#reset-non-separator-tokens) ```ts client.index('myIndex').resetNonSeparatorTokens(): Promise @@ -943,24 +943,44 @@ client.index('myIndex').resetNonSeparatorTokens(): Promise ### Dictionary -#### Get dictionary +#### [Get dictionary](https://www.meilisearch.com/docs/reference/api/settings#get-dictionary) ```ts client.index('myIndex').getDictionary(): Promise ``` -#### Update dictionary +#### [Update dictionary](https://www.meilisearch.com/docs/reference/api/settings#update-dictionary) ```ts client.index('myIndex').updateDictionary(dictionary: Dictionary | null): Promise ``` -#### Reset dictionary +#### [Reset dictionary](https://www.meilisearch.com/docs/reference/api/settings#reset-dictionary) ```ts client.index('myIndex').resetDictionary(): Promise ``` +### Proximity Precision + +#### [Get proximity precision](https://www.meilisearch.com/docs/reference/api/settings#get-prximity-precision) + +```ts +client.index('myIndex').getProximityPrecision(): Promise +``` + +#### [Update proximity precision](https://www.meilisearch.com/docs/reference/api/settings#update-proximity-precision) + +```ts +client.index('myIndex').updateProximityPrecision(proximityPrecision: ProximityPrecision): Promise +``` + +#### [Reset proximity precision](https://www.meilisearch.com/docs/reference/api/settings#reset-proximity-precision) + +```ts +client.index('myIndex').resetProximityPrecision(): Promise +``` + ### Keys #### [Get keys](https://www.meilisearch.com/docs/reference/api/keys#get-all-keys) diff --git a/src/indexes.ts b/src/indexes.ts index 39b338a7e..85509e57e 100644 --- a/src/indexes.ts +++ b/src/indexes.ts @@ -50,6 +50,7 @@ import { SeparatorTokens, NonSeparatorTokens, Dictionary, + ProximityPrecision, } from './types' import { removeUndefinedFromObject } from './utils' import { HttpRequests } from './http-requests' @@ -1222,7 +1223,7 @@ class Index = Record> { } /** - * Update the the dictionary settings. Overwrite the old settings. + * Update the dictionary settings. Overwrite the old settings. * * @param dictionary - Array that contains the new dictionary settings. * @returns Promise containing an EnqueuedTask or null @@ -1247,6 +1248,50 @@ class Index = Record> { return task } + + /// + /// PROXIMITY PRECISION + /// + + /** + * Get the proximity precision settings of a Meilisearch index. + * + * @returns Promise containing the proximity precision settings + */ + async getProximityPrecision(): Promise { + const url = `indexes/${this.uid}/settings/proximity-precision` + return await this.httpRequest.get(url) + } + + /** + * Update the proximity precision settings. Overwrite the old settings. + * + * @param proximityPrecision - String that contains the new proximity + * precision settings. + * @returns Promise containing an EnqueuedTask or null + */ + async updateProximityPrecision( + proximityPrecision: ProximityPrecision + ): Promise { + const url = `indexes/${this.uid}/settings/proximity-precision` + const task = await this.httpRequest.put(url, proximityPrecision) + + return new EnqueuedTask(task) + } + + /** + * Reset the proximity precision settings to its default value + * + * @returns Promise containing an EnqueuedTask + */ + async resetProximityPrecision(): Promise { + const url = `indexes/${this.uid}/settings/proximity-precision` + const task = await this.httpRequest.delete(url) + + task.enqueuedAt = new Date(task.enqueuedAt) + + return task + } } export { Index } diff --git a/src/types/types.ts b/src/types/types.ts index d9fbf8b7b..ee6b06c7b 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -316,6 +316,7 @@ export type TypoTolerance = { export type SeparatorTokens = string[] | null export type NonSeparatorTokens = string[] | null export type Dictionary = string[] | null +export type ProximityPrecision = 'byWord' | 'byAttribute' export type FacetOrder = 'alpha' | 'count' @@ -343,6 +344,7 @@ export type Settings = { separatorTokens?: SeparatorTokens nonSeparatorTokens?: NonSeparatorTokens dictionary?: Dictionary + proximityPrecision?: ProximityPrecision } /* diff --git a/tests/__snapshots__/settings.test.ts.snap b/tests/__snapshots__/settings.test.ts.snap index 158884d15..580d73338 100644 --- a/tests/__snapshots__/settings.test.ts.snap +++ b/tests/__snapshots__/settings.test.ts.snap @@ -18,6 +18,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, + "proximityPrecision": null, "rankingRules": Array [ "words", "typo", @@ -63,6 +64,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, + "proximityPrecision": null, "rankingRules": Array [ "words", "typo", @@ -108,6 +110,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, + "proximityPrecision": null, "rankingRules": Array [ "words", "typo", @@ -153,6 +156,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, + "proximityPrecision": null, "rankingRules": Array [ "words", "typo", @@ -198,6 +202,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, + "proximityPrecision": null, "rankingRules": Array [ "words", "typo", @@ -243,6 +248,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, + "proximityPrecision": null, "rankingRules": Array [ "words", "typo", @@ -297,6 +303,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, + "proximityPrecision": "byAttribute", "rankingRules": Array [ "id:asc", "typo", @@ -354,6 +361,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, + "proximityPrecision": null, "rankingRules": Array [ "title:asc", "typo", @@ -397,6 +405,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, + "proximityPrecision": null, "rankingRules": Array [ "words", "typo", @@ -442,6 +451,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, + "proximityPrecision": null, "rankingRules": Array [ "words", "typo", @@ -487,6 +497,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, + "proximityPrecision": null, "rankingRules": Array [ "words", "typo", @@ -532,6 +543,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, + "proximityPrecision": null, "rankingRules": Array [ "words", "typo", @@ -577,6 +589,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, + "proximityPrecision": null, "rankingRules": Array [ "words", "typo", @@ -622,6 +635,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, + "proximityPrecision": null, "rankingRules": Array [ "words", "typo", @@ -667,6 +681,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, + "proximityPrecision": null, "rankingRules": Array [ "words", "typo", @@ -721,6 +736,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, + "proximityPrecision": "byAttribute", "rankingRules": Array [ "id:asc", "typo", @@ -778,6 +794,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, + "proximityPrecision": null, "rankingRules": Array [ "title:asc", "typo", @@ -821,6 +838,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, + "proximityPrecision": null, "rankingRules": Array [ "words", "typo", diff --git a/tests/proximity_precision.test.ts b/tests/proximity_precision.test.ts new file mode 100644 index 000000000..134d92a09 --- /dev/null +++ b/tests/proximity_precision.test.ts @@ -0,0 +1,134 @@ +import { EnqueuedTask } from '../src/enqueued-task' +import { + clearAllIndexes, + config, + BAD_HOST, + MeiliSearch, + getClient, + dataset, +} from './utils/meilisearch-test-utils' + +const index = { + uid: 'movies_test', +} + +jest.setTimeout(100 * 1000) + +afterAll(() => { + return clearAllIndexes(config) +}) + +describe.each([{ permission: 'Master' }, { permission: 'Admin' }])( + 'Test on proximity precision', + ({ permission }) => { + beforeEach(async () => { + const client = await getClient('Master') + const { taskUid } = await client.index(index.uid).addDocuments(dataset) + await client.waitForTask(taskUid) + }) + + test(`${permission} key: Get default proximity precision`, async () => { + const client = await getClient(permission) + const response: string = await client + .index(index.uid) + .getProximityPrecision() + + expect(response).toEqual(null) + }) + + test(`${permission} key: Update proximity precision with 'byAttribute' value`, async () => { + const client = await getClient(permission) + const newProximityPrecision = 'byAttribute' + const task: EnqueuedTask = await client + .index(index.uid) + .updateProximityPrecision(newProximityPrecision) + await client.index(index.uid).waitForTask(task.taskUid) + + const response: string = await client + .index(index.uid) + .getProximityPrecision() + + expect(response).toEqual(newProximityPrecision) + }) + + test(`${permission} key: Update proximity precision with 'byWord' value`, async () => { + const client = await getClient(permission) + const newProximityPrecision = 'byWord' + const task: EnqueuedTask = await client + .index(index.uid) + .updateProximityPrecision(newProximityPrecision) + await client.index(index.uid).waitForTask(task.taskUid) + + const response: string = await client + .index(index.uid) + .getProximityPrecision() + + expect(response).toEqual(newProximityPrecision) + }) + + test(`${permission} key: Reset proximity precision`, async () => { + const client = await getClient(permission) + const task: EnqueuedTask = await client + .index(index.uid) + .resetProximityPrecision() + await client.index(index.uid).waitForTask(task.taskUid) + + const response: string = await client + .index(index.uid) + .getProximityPrecision() + + expect(response).toEqual(null) + }) + } +) + +describe.each([ + { host: BAD_HOST, trailing: false }, + { host: `${BAD_HOST}/api`, trailing: false }, + { host: `${BAD_HOST}/trailing/`, trailing: true }, +])('Tests on url construction', ({ host, trailing }) => { + test(`Test getProximityPrecision route`, async () => { + const route = `indexes/${index.uid}/settings/proximity-precision` + const client = new MeiliSearch({ host }) + const strippedHost = trailing ? host.slice(0, -1) : host + await expect( + client.index(index.uid).getProximityPrecision() + ).rejects.toHaveProperty( + 'message', + `request to ${strippedHost}/${route} failed, reason: connect ECONNREFUSED ${BAD_HOST.replace( + 'http://', + '' + )}` + ) + }) + + test(`Test updateProximityPrecision route`, async () => { + const route = `indexes/${index.uid}/settings/proximity-precision` + const client = new MeiliSearch({ host }) + const strippedHost = trailing ? host.slice(0, -1) : host + await expect( + client.index(index.uid).updateProximityPrecision('byAttribute') + ).rejects.toHaveProperty( + 'message', + `request to ${strippedHost}/${route} failed, reason: connect ECONNREFUSED ${BAD_HOST.replace( + 'http://', + '' + )}` + ) + }) + + test(`Test resetProximityPrecision route`, async () => { + const route = `indexes/${index.uid}/settings/proximity-precision` + const client = new MeiliSearch({ host }) + const strippedHost = trailing ? host.slice(0, -1) : host + await expect( + client.index(index.uid).resetProximityPrecision() + ).rejects.toHaveProperty( + 'message', + `request to ${strippedHost}/${route} failed, reason: connect ECONNREFUSED ${BAD_HOST.replace( + 'http://', + '' + )}` + ) + }) +}) diff --git a/tests/settings.test.ts b/tests/settings.test.ts index e59a4f5a5..4316c84ae 100644 --- a/tests/settings.test.ts +++ b/tests/settings.test.ts @@ -63,6 +63,7 @@ describe.each([{ permission: 'Master' }, { permission: 'Admin' }])( filterableAttributes: ['title'], sortableAttributes: ['title'], distinctAttribute: 'title', + proximityPrecision: 'byAttribute', searchableAttributes: ['title'], displayedAttributes: ['title'], rankingRules: ['id:asc', 'typo'], From 4e5fd5858dc5c2a7e86abadb5ea91d6c2df73538 Mon Sep 17 00:00:00 2001 From: Morgane Dubus Date: Tue, 9 Jan 2024 08:56:51 +0100 Subject: [PATCH 2/2] Update proximity precision default value byWord --- tests/__snapshots__/settings.test.ts.snap | 32 +++++++++++------------ tests/proximity_precision.test.ts | 4 +-- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/tests/__snapshots__/settings.test.ts.snap b/tests/__snapshots__/settings.test.ts.snap index 580d73338..e968b5b71 100644 --- a/tests/__snapshots__/settings.test.ts.snap +++ b/tests/__snapshots__/settings.test.ts.snap @@ -18,7 +18,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, - "proximityPrecision": null, + "proximityPrecision": "byWord", "rankingRules": Array [ "words", "typo", @@ -64,7 +64,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, - "proximityPrecision": null, + "proximityPrecision": "byWord", "rankingRules": Array [ "words", "typo", @@ -110,7 +110,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, - "proximityPrecision": null, + "proximityPrecision": "byWord", "rankingRules": Array [ "words", "typo", @@ -156,7 +156,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, - "proximityPrecision": null, + "proximityPrecision": "byWord", "rankingRules": Array [ "words", "typo", @@ -202,7 +202,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, - "proximityPrecision": null, + "proximityPrecision": "byWord", "rankingRules": Array [ "words", "typo", @@ -248,7 +248,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, - "proximityPrecision": null, + "proximityPrecision": "byWord", "rankingRules": Array [ "words", "typo", @@ -361,7 +361,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, - "proximityPrecision": null, + "proximityPrecision": "byWord", "rankingRules": Array [ "title:asc", "typo", @@ -405,7 +405,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, - "proximityPrecision": null, + "proximityPrecision": "byWord", "rankingRules": Array [ "words", "typo", @@ -451,7 +451,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, - "proximityPrecision": null, + "proximityPrecision": "byWord", "rankingRules": Array [ "words", "typo", @@ -497,7 +497,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, - "proximityPrecision": null, + "proximityPrecision": "byWord", "rankingRules": Array [ "words", "typo", @@ -543,7 +543,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, - "proximityPrecision": null, + "proximityPrecision": "byWord", "rankingRules": Array [ "words", "typo", @@ -589,7 +589,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, - "proximityPrecision": null, + "proximityPrecision": "byWord", "rankingRules": Array [ "words", "typo", @@ -635,7 +635,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, - "proximityPrecision": null, + "proximityPrecision": "byWord", "rankingRules": Array [ "words", "typo", @@ -681,7 +681,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, - "proximityPrecision": null, + "proximityPrecision": "byWord", "rankingRules": Array [ "words", "typo", @@ -794,7 +794,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, - "proximityPrecision": null, + "proximityPrecision": "byWord", "rankingRules": Array [ "title:asc", "typo", @@ -838,7 +838,7 @@ Object { "pagination": Object { "maxTotalHits": 1000, }, - "proximityPrecision": null, + "proximityPrecision": "byWord", "rankingRules": Array [ "words", "typo", diff --git a/tests/proximity_precision.test.ts b/tests/proximity_precision.test.ts index 134d92a09..82e9d3afb 100644 --- a/tests/proximity_precision.test.ts +++ b/tests/proximity_precision.test.ts @@ -33,7 +33,7 @@ describe.each([{ permission: 'Master' }, { permission: 'Admin' }])( .index(index.uid) .getProximityPrecision() - expect(response).toEqual(null) + expect(response).toEqual('byWord') }) test(`${permission} key: Update proximity precision with 'byAttribute' value`, async () => { @@ -77,7 +77,7 @@ describe.each([{ permission: 'Master' }, { permission: 'Admin' }])( .index(index.uid) .getProximityPrecision() - expect(response).toEqual(null) + expect(response).toEqual('byWord') }) } )