Skip to content

Commit

Permalink
Add federated search parameters (#1689)
Browse files Browse the repository at this point in the history
* Remove cross-fetch dependency

* Add types for federation feature

* Add test, minor changes to types

* Revert "Remove cross-fetch dependency"

This reverts commit 899d2a7.

* Revert generic name back to T for consistency

* Revert rest of the generics to T

* Remove focus from test

* Revert changes to test-utils getClient

* Add back accidentally removed type from test utils
  • Loading branch information
flevi29 authored Aug 22, 2024
1 parent 30e833f commit 3a8608b
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 12 deletions.
18 changes: 13 additions & 5 deletions src/clients/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
* Copyright: 2019, MeiliSearch
*/

'use strict';

import { Index } from '../indexes';
import {
KeyCreation,
Expand Down Expand Up @@ -34,6 +32,8 @@ import {
DeleteTasksQuery,
MultiSearchParams,
MultiSearchResponse,
SearchResponse,
FederatedMultiSearchParams,
} from '../types';
import { HttpRequests } from '../http-requests';
import { TaskClient, Task } from '../task';
Expand Down Expand Up @@ -216,10 +216,18 @@ class Client {
* @param config - Additional request configuration options
* @returns Promise containing the search responses
*/
async multiSearch<T extends Record<string, any> = Record<string, any>>(
queries?: MultiSearchParams,
multiSearch<T extends Record<string, unknown> = Record<string, any>>(
queries: MultiSearchParams,
config?: Partial<Request>,
): Promise<MultiSearchResponse<T>>;
multiSearch<T extends Record<string, unknown> = Record<string, any>>(
queries: FederatedMultiSearchParams,
config?: Partial<Request>,
): Promise<SearchResponse<T>>;
async multiSearch<T extends Record<string, unknown> = Record<string, any>>(
queries: MultiSearchParams | FederatedMultiSearchParams,
config?: Partial<Request>,
): Promise<MultiSearchResponse<T>> {
): Promise<MultiSearchResponse<T> | SearchResponse<T>> {
const url = `multi-search`;

return await this.httpRequest.post(url, queries, undefined, config);
Expand Down
31 changes: 24 additions & 7 deletions src/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,21 @@ export type SearchRequestGET = Pagination &
locales?: Locale[];
};

export type FederationOptions = { weight: number };
export type MultiSearchFederation = { limit?: number; offset?: number };

export type MultiSearchQuery = SearchParams & { indexUid: string };
export type MultiSearchQueryWithFederation = MultiSearchQuery & {
federationOptions?: FederationOptions;
};

export type MultiSearchParams = {
queries: MultiSearchQuery[];
};
export type FederatedMultiSearchParams = {
federation: MultiSearchFederation;
queries: MultiSearchQueryWithFederation[];
};

export type CategoriesDistribution = {
[category: string]: number;
Expand All @@ -175,13 +185,6 @@ export type MatchesPosition<T> = Partial<
Record<keyof T, Array<{ start: number; length: number }>>
>;

export type Hit<T = Record<string, any>> = T & {
_formatted?: Partial<T>;
_matchesPosition?: MatchesPosition<T>;
_rankingScore?: number;
_rankingScoreDetails?: RankingScoreDetails;
};

export type RankingScoreDetails = {
words?: {
order: number;
Expand Down Expand Up @@ -213,6 +216,20 @@ export type RankingScoreDetails = {
[key: string]: Record<string, any> | undefined;
};

export type FederationDetails = {
indexUid: string;
queriesPosition: number;
weightedRankingScore: number;
};

export type Hit<T = Record<string, any>> = T & {
_formatted?: Partial<T>;
_matchesPosition?: MatchesPosition<T>;
_rankingScore?: number;
_rankingScoreDetails?: RankingScoreDetails;
_federation?: FederationDetails;
};

export type Hits<T = Record<string, any>> = Array<Hit<T>>;

export type FacetStat = { min: number; max: number };
Expand Down
42 changes: 42 additions & 0 deletions tests/search.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,48 @@ describe.each([
expect(response.results[0].hits[0].title).toEqual('Le Petit Prince');
});

test(`${permission} key: Multi index search with federation`, async () => {
const client = await getClient(permission);

const response1 = await client.multiSearch<
Books | { id: number; asd: string }
>({
federation: {},
queries: [
{ indexUid: index.uid, q: '456', attributesToSearchOn: ['id'] },
{
indexUid: index.uid,
q: '1344',
federationOptions: { weight: 0.9 },
attributesToSearchOn: ['id'],
},
],
});

expect(response1).toHaveProperty('hits');
expect(Array.isArray(response1.hits)).toBe(true);
expect(response1.hits.length).toEqual(2);
expect(response1.hits[0].id).toEqual(456);

const response2 = await client.multiSearch({
federation: {},
queries: [
{
indexUid: index.uid,
q: '456',
federationOptions: { weight: 0.9 },
attributesToSearchOn: ['id'],
},
{ indexUid: index.uid, q: '1344', attributesToSearchOn: ['id'] },
],
});

expect(response2).toHaveProperty('hits');
expect(Array.isArray(response2.hits)).toBe(true);
expect(response2.hits.length).toEqual(2);
expect(response2.hits[0].id).toEqual(1344);
});

test(`${permission} key: Basic search`, async () => {
const client = await getClient(permission);
const response = await client.index(index.uid).search('prince', {});
Expand Down

0 comments on commit 3a8608b

Please sign in to comment.