Skip to content

Commit 8e56525

Browse files
authored
feat: hybrid search changes (#1679)
1 parent 65bc592 commit 8e56525

File tree

4 files changed

+173
-0
lines changed

4 files changed

+173
-0
lines changed

src/types/types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ export type SearchParams = Query &
129129
attributesToSearchOn?: string[] | null;
130130
hybrid?: HybridSearch;
131131
distinct?: string;
132+
retrieveVectors?: boolean;
132133
};
133134

134135
// Search parameters for searches made with the GET method
@@ -150,6 +151,7 @@ export type SearchRequestGET = Pagination &
150151
hybridSemanticRatio?: number;
151152
rankingScoreThreshold?: number;
152153
distinct?: string;
154+
retrieveVectors?: boolean;
153155
};
154156

155157
export type MultiSearchQuery = SearchParams & { indexUid: string };
@@ -311,6 +313,7 @@ export type DocumentsQuery<T = Record<string, any>> = ResourceQuery & {
311313
filter?: Filter;
312314
limit?: number;
313315
offset?: number;
316+
retrieveVectors?: boolean;
314317
};
315318

316319
export type DocumentQuery<T = Record<string, any>> = {

tests/documents.test.ts

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,92 @@ Hint: It might not be working because maybe you're not up to date with the Meili
218218
expect(documents.results.length).toEqual(dataset.length);
219219
});
220220

221+
test(`${permission} key: Get documents with retrieveVectors to true`, async () => {
222+
const client = await getClient(permission);
223+
const adminKey = await getKey('Admin');
224+
225+
await fetch(`${HOST}/experimental-features`, {
226+
body: JSON.stringify({ vectorStore: true }),
227+
headers: {
228+
Authorization: `Bearer ${adminKey}`,
229+
'Content-Type': 'application/json',
230+
},
231+
method: 'PATCH',
232+
});
233+
234+
const { taskUid } = await client
235+
.index(indexPk.uid)
236+
.addDocuments(dataset);
237+
await client.index(indexPk.uid).waitForTask(taskUid);
238+
239+
// Get documents with POST
240+
const documentsPost = await client
241+
.index(indexPk.uid)
242+
.getDocuments<Book>({ retrieveVectors: true });
243+
244+
expect(documentsPost.results.length).toEqual(dataset.length);
245+
expect(documentsPost.results[0]).toHaveProperty('_vectors');
246+
247+
// Get documents with GET
248+
const res = await fetch(
249+
`${HOST}/indexes/${indexPk.uid}/documents?retrieveVectors=true`,
250+
{
251+
headers: {
252+
Authorization: `Bearer ${adminKey}`,
253+
'Content-Type': 'application/json',
254+
},
255+
method: 'GET',
256+
},
257+
);
258+
const documentsGet = await res.json();
259+
260+
expect(documentsGet.results.length).toEqual(dataset.length);
261+
expect(documentsGet.results[0]).toHaveProperty('_vectors');
262+
});
263+
264+
test(`${permission} key: Get documents without retrieveVectors`, async () => {
265+
const client = await getClient(permission);
266+
const adminKey = await getKey('Admin');
267+
268+
await fetch(`${HOST}/experimental-features`, {
269+
body: JSON.stringify({ vectorStore: true }),
270+
headers: {
271+
Authorization: `Bearer ${adminKey}`,
272+
'Content-Type': 'application/json',
273+
},
274+
method: 'PATCH',
275+
});
276+
277+
const { taskUid } = await client
278+
.index(indexPk.uid)
279+
.addDocuments(dataset);
280+
await client.index(indexPk.uid).waitForTask(taskUid);
281+
282+
// Get documents with POST
283+
const documentsPost = await client
284+
.index(indexPk.uid)
285+
.getDocuments<Book>();
286+
287+
expect(documentsPost.results.length).toEqual(dataset.length);
288+
expect(documentsPost.results[0]).not.toHaveProperty('_vectors');
289+
290+
// Get documents with GET
291+
const res = await fetch(
292+
`${HOST}/indexes/${indexPk.uid}/documents?retrieveVectors=false`,
293+
{
294+
headers: {
295+
Authorization: `Bearer ${adminKey}`,
296+
'Content-Type': 'application/json',
297+
},
298+
method: 'GET',
299+
},
300+
);
301+
const documentsGet = await res.json();
302+
303+
expect(documentsGet.results.length).toEqual(dataset.length);
304+
expect(documentsGet.results[0]).not.toHaveProperty('_vectors');
305+
});
306+
221307
test(`${permission} key: Replace documents from index that has NO primary key`, async () => {
222308
const client = await getClient(permission);
223309
const { taskUid: addDocTask } = await client

tests/get_search.test.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,48 @@ describe.each([
520520
expect(response.hits.length).toEqual(4);
521521
});
522522

523+
test(`${permission} key: search with retrieveVectors to true`, async () => {
524+
const client = await getClient(permission);
525+
const adminKey = await getKey('Admin');
526+
527+
await fetch(`${HOST}/experimental-features`, {
528+
body: JSON.stringify({ vectorStore: true }),
529+
headers: {
530+
Authorization: `Bearer ${adminKey}`,
531+
'Content-Type': 'application/json',
532+
},
533+
method: 'PATCH',
534+
});
535+
536+
const response = await client.index(index.uid).searchGet('prince', {
537+
retrieveVectors: true,
538+
});
539+
540+
expect(response).toHaveProperty('hits', expect.any(Array));
541+
expect(response).toHaveProperty('query', 'prince');
542+
expect(response.hits[0]).toHaveProperty('_vectors');
543+
});
544+
545+
test(`${permission} key: search without retrieveVectors`, async () => {
546+
const client = await getClient(permission);
547+
const adminKey = await getKey('Admin');
548+
549+
await fetch(`${HOST}/experimental-features`, {
550+
body: JSON.stringify({ vectorStore: true }),
551+
headers: {
552+
Authorization: `Bearer ${adminKey}`,
553+
'Content-Type': 'application/json',
554+
},
555+
method: 'PATCH',
556+
});
557+
558+
const response = await client.index(index.uid).searchGet('prince');
559+
560+
expect(response).toHaveProperty('hits', expect.any(Array));
561+
expect(response).toHaveProperty('query', 'prince');
562+
expect(response.hits[0]).not.toHaveProperty('_vectors');
563+
});
564+
523565
test(`${permission} key: Try to search on deleted index and fail`, async () => {
524566
const client = await getClient(permission);
525567
const masterClient = await getClient('Master');

tests/search.test.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,48 @@ describe.each([
920920
expect(response.hits.length).toEqual(4);
921921
});
922922

923+
test(`${permission} key: search with retrieveVectors to true`, async () => {
924+
const client = await getClient(permission);
925+
const adminKey = await getKey('Admin');
926+
927+
await fetch(`${HOST}/experimental-features`, {
928+
body: JSON.stringify({ vectorStore: true }),
929+
headers: {
930+
Authorization: `Bearer ${adminKey}`,
931+
'Content-Type': 'application/json',
932+
},
933+
method: 'PATCH',
934+
});
935+
936+
const response = await client.index(index.uid).search('prince', {
937+
retrieveVectors: true,
938+
});
939+
940+
expect(response).toHaveProperty('hits', expect.any(Array));
941+
expect(response).toHaveProperty('query', 'prince');
942+
expect(response.hits[0]).toHaveProperty('_vectors');
943+
});
944+
945+
test(`${permission} key: search without retrieveVectors`, async () => {
946+
const client = await getClient(permission);
947+
const adminKey = await getKey('Admin');
948+
949+
await fetch(`${HOST}/experimental-features`, {
950+
body: JSON.stringify({ vectorStore: true }),
951+
headers: {
952+
Authorization: `Bearer ${adminKey}`,
953+
'Content-Type': 'application/json',
954+
},
955+
method: 'PATCH',
956+
});
957+
958+
const response = await client.index(index.uid).search('prince');
959+
960+
expect(response).toHaveProperty('hits', expect.any(Array));
961+
expect(response).toHaveProperty('query', 'prince');
962+
expect(response.hits[0]).not.toHaveProperty('_vectors');
963+
});
964+
923965
test(`${permission} key: Try to search on deleted index and fail`, async () => {
924966
const client = await getClient(permission);
925967
const masterClient = await getClient('Master');

0 commit comments

Comments
 (0)