Skip to content

Commit 75d7f34

Browse files
committed
Add the searchForFacetValue method
1 parent d85d9b8 commit 75d7f34

File tree

4 files changed

+162
-0
lines changed

4 files changed

+162
-0
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,14 @@ client.multiSearch(queries?: MultiSearchParams, config?: Partial<Request>): Prom
412412

413413
`multiSearch` uses the `POST` method when performing its request to Meilisearch.
414414

415+
### Search For Facet Value
416+
417+
#### [Search for facet value](#)
418+
419+
```ts
420+
client.index<T>('xxx').searchForFacetValue(params: SearchForFacetValuesParams, config?: Partial<Request>): Promise<SearchForFacetValuesResponse>
421+
```
422+
415423
### Documents <!-- omit in toc -->
416424

417425
#### [Add or replace multiple documents](https://www.meilisearch.com/docs/reference/api/documents#add-or-replace-documents)

src/indexes.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ import {
4545
ContentType,
4646
DocumentsIds,
4747
DocumentsDeletionQuery,
48+
SearchForFacetValuesParams,
49+
SearchForFacetValuesResponse,
4850
} from './types'
4951
import { removeUndefinedFromObject } from './utils'
5052
import { HttpRequests } from './http-requests'
@@ -146,6 +148,27 @@ class Index<T extends Record<string, any> = Record<string, any>> {
146148
)
147149
}
148150

151+
/**
152+
* Search for facet values
153+
*
154+
* @param params - Parameters used to search on the facets
155+
* @param config - Additional request configuration options
156+
* @returns Promise containing the search response
157+
*/
158+
async searchForFacetValue(
159+
params: SearchForFacetValuesParams,
160+
config?: Partial<Request>
161+
): Promise<SearchForFacetValuesResponse> {
162+
const url = `indexes/${this.uid}/facet-search`
163+
164+
return await this.httpRequest.post(
165+
url,
166+
removeUndefinedFromObject(params),
167+
undefined,
168+
config
169+
)
170+
}
171+
149172
///
150173
/// INDEX
151174
///

src/types/types.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,29 @@ export type FieldDistribution = {
189189
[field: string]: number
190190
}
191191

192+
/*
193+
* Facet search
194+
*/
195+
196+
export type SearchForFacetValuesParams = SearchParams & {
197+
facetName: string
198+
facetQuery?: string
199+
q?: string
200+
filter?: Filter
201+
matchingStrategy?: MatchingStrategies
202+
}
203+
204+
export type FacetHit = {
205+
value: string
206+
count: number
207+
}
208+
209+
export type SearchForFacetValuesResponse = {
210+
hits: FacetHit[]
211+
query: string | null
212+
processingTimeMs: number
213+
}
214+
192215
/*
193216
** Documents
194217
*/

tests/facet_search.test.ts

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import {
2+
clearAllIndexes,
3+
config,
4+
getClient,
5+
} from './utils/meilisearch-test-utils'
6+
7+
const index = {
8+
uid: 'movies_test',
9+
}
10+
11+
const dataset = [
12+
{
13+
id: 123,
14+
title: 'Pride and Prejudice',
15+
genres: ['romance', 'action'],
16+
},
17+
{
18+
id: 456,
19+
title: 'Le Petit Prince',
20+
genres: ['adventure', 'comedy'],
21+
},
22+
{
23+
id: 2,
24+
title: 'Le Rouge et le Noir',
25+
genres: 'romance',
26+
},
27+
{
28+
id: 1,
29+
title: 'Alice In Wonderland',
30+
genres: ['adventure'],
31+
},
32+
]
33+
34+
describe.each([
35+
{ permission: 'Master' },
36+
{ permission: 'Admin' },
37+
{ permission: 'Search' },
38+
])('Test on POST search', ({ permission }) => {
39+
beforeAll(async () => {
40+
await clearAllIndexes(config)
41+
const client = await getClient('Master')
42+
const newFilterableAttributes = ['genres', 'title']
43+
44+
await client.createIndex(index.uid)
45+
await client.index(index.uid).updateSettings({
46+
filterableAttributes: newFilterableAttributes,
47+
})
48+
const { taskUid } = await client.index(index.uid).addDocuments(dataset)
49+
await client.waitForTask(taskUid)
50+
})
51+
52+
test(`${permission} key: basic facet value search`, async () => {
53+
const client = await getClient(permission)
54+
55+
const params = {
56+
facetQuery: 'a',
57+
facetName: 'genres',
58+
}
59+
const response = await client.index(index.uid).searchForFacetValue(params)
60+
61+
expect(response.hits.length).toEqual(2)
62+
expect(response.query).toEqual('a')
63+
})
64+
65+
test(`${permission} key: facet value search with no facet query`, async () => {
66+
const client = await getClient(permission)
67+
68+
const params = {
69+
facetName: 'genres',
70+
}
71+
const response = await client.index(index.uid).searchForFacetValue(params)
72+
73+
expect(response.hits.length).toEqual(4)
74+
expect(response.query).toEqual(null)
75+
})
76+
77+
test(`${permission} key: facet value search with filter`, async () => {
78+
const client = await getClient(permission)
79+
80+
const params = {
81+
facetName: 'genres',
82+
facetQuery: 'a',
83+
filter: ['genres = action'],
84+
}
85+
const response = await client.index(index.uid).searchForFacetValue(params)
86+
87+
expect(response.hits.length).toEqual(1)
88+
})
89+
90+
test(`${permission} key: facet value search with search query`, async () => {
91+
const client = await getClient(permission)
92+
93+
const params = {
94+
facetName: 'genres',
95+
facetQuery: 'a',
96+
q: 'Alice',
97+
}
98+
const response = await client.index(index.uid).searchForFacetValue(params)
99+
100+
expect(response.hits.length).toEqual(1)
101+
})
102+
})
103+
104+
jest.setTimeout(100 * 1000)
105+
106+
afterAll(() => {
107+
return clearAllIndexes(config)
108+
})

0 commit comments

Comments
 (0)