Skip to content

Commit

Permalink
fixup! feat: added strong typed orama schema
Browse files Browse the repository at this point in the history
  • Loading branch information
H4ad committed Sep 6, 2023
1 parent 6b42ca2 commit c78278b
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 114 deletions.
2 changes: 1 addition & 1 deletion packages/orama/src/components/facets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function sortingPredicate(order: FacetSorting = 'desc', a: [string, number], b:
export async function getFacets<T extends AnyOrama>(
orama: T,
results: TokenScore[],
facetsConfig: FacetsParams,
facetsConfig: FacetsParams<T>,
): Promise<FacetResult> {
const facets: FacetResult = {}
const allIDs = results.map(([id]) => id)
Expand Down
2 changes: 1 addition & 1 deletion packages/orama/src/components/groups.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const ALLOWED_TYPES = ['string', 'number', 'boolean']
export async function getGroups<T extends AnyOrama, ResultDocument = TypedDocument<T>>(
orama: T,
results: TokenScore[],
groupBy: GroupByParams<ResultDocument>,
groupBy: GroupByParams<T, ResultDocument>,
): Promise<GroupResult<ResultDocument>> {
const properties = groupBy.properties
const propertiesLength = properties.length
Expand Down
36 changes: 18 additions & 18 deletions packages/orama/src/methods/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,21 @@ import {
} from '../components/internal-document-id-store.js'
import { createError } from '../errors.js'
import type {
AnyOrama,
BM25Params,
CustomSorterFunctionItem,
ElapsedTime,
IndexMap,
Result,
Results,
SearchContext,
SearchParams,
SearchableValue,
TokenMap,
TokenScore,
Tokenizer,
TypedDocument,
} from '../types.js'
AnyOrama,
BM25Params,
CustomSorterFunctionItem,
ElapsedTime,
IndexMap,
Result,
Results,
SearchContext,
SearchParams,
SearchableValue,
TokenMap,
TokenScore,
Tokenizer,
TypedDocument, LiteralUnion,
} from '../types.js';
import { getNanosecondsTime, getNested, sortTokenScorePredicate } from '../utils.js'

const defaultBM25Params: BM25Params = {
Expand Down Expand Up @@ -132,8 +132,8 @@ export async function search<T extends AnyOrama, ResultDocument = TypedDocument<

if (properties && properties !== '*') {
for (const prop of properties) {
if (!propertiesToSearch.includes(prop)) {
throw createError('UNKNOWN_INDEX', prop, propertiesToSearch.join(', '))
if (!propertiesToSearch.includes(prop as string)) {
throw createError('UNKNOWN_INDEX', prop as string, propertiesToSearch.join(', '))
}
}

Expand Down Expand Up @@ -284,7 +284,7 @@ async function fetchDocumentsWithDistinct<T extends AnyOrama, ResultDocument ext
uniqueDocsArray: [InternalDocumentID, number][],
offset: number,
limit: number,
distinctOn: string,
distinctOn: LiteralUnion<T['schema']>,
): Promise<Result<ResultDocument>[]> {
const docs = orama.data.docs

Expand Down
28 changes: 15 additions & 13 deletions packages/orama/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export type SchemaTypes<Value> = Value extends 'string'
: Value extends 'number[]'
? number[]
: // eslint-disable-next-line @typescript-eslint/no-unused-vars
Value extends `vector[${infer Size extends number}]`
Value extends `vector[${number}]`
? number[]
: Value extends object
? { [Key in keyof Value]: SchemaTypes<Value[Key]> } & {
Expand Down Expand Up @@ -109,7 +109,7 @@ export interface BooleanFacetDefinition {
false?: boolean
}

export type FacetsParams = Record<string, FacetDefinition>
export type FacetsParams<T extends AnyOrama> = Partial<Record<LiteralUnion<T['schema']>, FacetDefinition>>

export type FacetDefinition = StringFacetDefinition | NumberFacetDefinition | BooleanFacetDefinition

Expand All @@ -119,10 +119,10 @@ export type Reduce<T, R = AnyDocument> = {
getInitialValue: (elementCount: number) => T
}

export type GroupByParams<T> = {
properties: string[]
export type GroupByParams<T extends AnyOrama, ResultDocument> = {
properties: LiteralUnion<T['schema']>[]
maxResult?: number
reduce?: Reduce<T>
reduce?: Reduce<ResultDocument>
}

export type ComparisonOperator = {
Expand All @@ -143,14 +143,16 @@ export type CustomSorterFunction<ResultDocument> = (
a: CustomSorterFunctionItem<ResultDocument>,
b: CustomSorterFunctionItem<ResultDocument>,
) => number
// thanks to https://github.com/sindresorhus/type-fest/blob/main/source/literal-union.d.ts
export type LiteralUnion<T> = (keyof T extends string ? keyof T : never) | (string & Record<never, never>)
/**
* Define which properties to sort for.
*/
export type SorterParams<T extends AnyOrama> = {
/**
* The key of the document used to sort the result.
*/
property: keyof T['schema'] extends string ? keyof T['schema'] : string;
property: LiteralUnion<T['schema']>;
/**
* Whether to sort the result in ascending or descending order.
*/
Expand All @@ -167,7 +169,7 @@ export type SearchParams<T extends AnyOrama, ResultDocument = TypedDocument<T>>
/**
* The properties of the document to search in.
*/
properties?: '*' | string[]
properties?: '*' | LiteralUnion<T['schema']>[]
/**
* The number of matched documents to return.
*/
Expand Down Expand Up @@ -226,7 +228,7 @@ export type SearchParams<T extends AnyOrama, ResultDocument = TypedDocument<T>>
*
* // In that case, the score of the 'title' property will be multiplied by 2.
*/
boost?: Record<string, number>
boost?: Partial<Record<LiteralUnion<T['schema']>, number>>
/**
* Facets configuration
* Full documentation: https://docs.oramasearch.com/usage/search/facets
Expand All @@ -248,7 +250,7 @@ export type SearchParams<T extends AnyOrama, ResultDocument = TypedDocument<T>>
* }
* });
*/
facets?: FacetsParams
facets?: FacetsParams<T>

/**
* Distinct configuration
Expand All @@ -260,7 +262,7 @@ export type SearchParams<T extends AnyOrama, ResultDocument = TypedDocument<T>>
* distinctOn: 'category.primary',
* })
*/
distinctOn?: string
distinctOn?: LiteralUnion<T['schema']>

/**
* Groups configuration
Expand All @@ -275,7 +277,7 @@ export type SearchParams<T extends AnyOrama, ResultDocument = TypedDocument<T>>
* }
* })
*/
groupBy?: GroupByParams<ResultDocument>
groupBy?: GroupByParams<T, ResultDocument>

/**
* Filter the search results.
Expand All @@ -295,7 +297,7 @@ export type SearchParams<T extends AnyOrama, ResultDocument = TypedDocument<T>>
* }
* });
*/
where?: Record<string, boolean | string | string[] | ComparisonOperator>
where?: Partial<Record<LiteralUnion<T['schema']>, boolean | string | string[] | ComparisonOperator>>

/**
* Threshold to use for refining the search results.
Expand Down Expand Up @@ -543,7 +545,7 @@ export interface IIndex<I extends AnyIndexStore> {
searchByWhereClause<T extends AnyOrama, ResultDocument = TypedDocument<T>>(
context: SearchContext<T, ResultDocument>,
index: I,
filters: Record<string, boolean | string | string[] | ComparisonOperator>,
filters: Partial<Record<LiteralUnion<T['schema']>, boolean | string | string[] | ComparisonOperator>>,
): SyncOrAsyncValue<InternalDocumentID[]>

getSearchableProperties(index: I): SyncOrAsyncValue<string[]>
Expand Down
11 changes: 4 additions & 7 deletions packages/orama/tests/sort.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import t from 'tap'
import { CustomSorterFunctionItem, create, insert, insertMultiple, load, remove, save, search } from '../src/index.js'
import { create, insert, insertMultiple, load, remove, save, search } from '../src/index.js'

t.test('search with sortBy', t => {
t.test('on number', async t => {
Expand Down Expand Up @@ -368,7 +368,7 @@ t.test('search with sortBy', t => {
number: 'number',
},
})
await t.rejects(search(db, { sortBy: { property: 'foobar' } }))
await t.rejects(search(db, { sortBy: { property: 'foobar' } as any }))

t.end()
})
Expand All @@ -388,9 +388,6 @@ t.test('search with sortBy', t => {
})

t.test('should allow custom function', async t => {
interface Doc {
string?: string
}
const db = await create({
schema: {
string: 'string',
Expand All @@ -406,8 +403,8 @@ t.test('search with sortBy', t => {
])

const result = await search(db, {
sortBy: (a: CustomSorterFunctionItem, b: CustomSorterFunctionItem) => {
return ((a[2] as unknown as Doc).string || '').localeCompare((b[2] as unknown as Doc).string || '')
sortBy: (a, b) => {
return (a[2].string || '').localeCompare(b[2].string || '')
},
})

Expand Down
4 changes: 2 additions & 2 deletions packages/plugin-match-highlight/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ async function recursivePositionInsertion<T extends AnyOrama, ResultDocument = T
}

export async function searchWithHighlight<T extends AnyOrama, ResultDocument = TypedDocument<T>>(
orama: OramaWithHighlight<T>,
orama: T,
params: SearchParams<T, ResultDocument>,
language?: Language
): Promise<SearchResultWithHighlight<ResultDocument>> {
Expand All @@ -92,7 +92,7 @@ export async function searchWithHighlight<T extends AnyOrama, ResultDocument = T
const hits = result.hits.map((hit: AnyDocument) =>
Object.assign(hit, {
positions: Object.fromEntries(
Object.entries<any>(orama.data.positions[hit.id]).map(([propName, tokens]) => [
Object.entries<any>((orama as OramaWithHighlight<T>).data.positions[hit.id]).map(([propName, tokens]) => [
propName,
Object.fromEntries(
Object.entries(tokens).filter(([token]) => queryTokens.find(queryToken => token.startsWith(queryToken)))
Expand Down
Loading

0 comments on commit c78278b

Please sign in to comment.