diff --git a/clients/ts-sdk/openapi.json b/clients/ts-sdk/openapi.json index bddfffda0e..8d3e0989fa 100644 --- a/clients/ts-sdk/openapi.json +++ b/clients/ts-sdk/openapi.json @@ -7190,11 +7190,6 @@ "type": "object", "description": "Filters is a JSON object which can be used to filter chunks. This is useful for when you want to filter chunks by arbitrary metadata. Unlike with tag filtering, there is a performance hit for filtering on metadata.", "properties": { - "jsonb_prefilter": { - "type": "boolean", - "description": "JOSNB prefilter tells the server to perform a full scan over the metadata JSONB column instead of using the filtered HNSW. Datasets on the enterprise plan with custom metadata indices will perform better with the filtered HNSW instead. When false, the server will use the filtered HNSW index to filter chunks. When true, the server will perform a full scan over the metadata JSONB column to filter chunks. Default is true.", - "nullable": true - }, "must": { "type": "array", "items": { @@ -15015,6 +15010,12 @@ ], "nullable": true }, + "recency_bias": { + "type": "number", + "format": "float", + "description": "Recency Bias lets you determine how much of an effect the recency of chunks will have on the search results. If not specified, this defaults to 0.0. We recommend setting this to 1.0 for a gentle reranking of the results, >3.0 for a strong reranking of the results.", + "nullable": true + }, "sort_by": { "allOf": [ { diff --git a/clients/ts-sdk/package.json b/clients/ts-sdk/package.json index 9f4c5a5eed..5c81d6913a 100644 --- a/clients/ts-sdk/package.json +++ b/clients/ts-sdk/package.json @@ -6,7 +6,7 @@ "files": [ "dist" ], - "version": "0.0.35", + "version": "0.0.36", "license": "MIT", "scripts": { "lint": "eslint 'src/**/*.ts'", diff --git a/clients/ts-sdk/src/types.gen.ts b/clients/ts-sdk/src/types.gen.ts index ced2853a2d..fd199eb8e1 100644 --- a/clients/ts-sdk/src/types.gen.ts +++ b/clients/ts-sdk/src/types.gen.ts @@ -209,10 +209,6 @@ export type ChatMessageProxy = { * Filters is a JSON object which can be used to filter chunks. This is useful for when you want to filter chunks by arbitrary metadata. Unlike with tag filtering, there is a performance hit for filtering on metadata. */ export type ChunkFilter = { - /** - * JOSNB prefilter tells the server to perform a full scan over the metadata JSONB column instead of using the filtered HNSW. Datasets on the enterprise plan with custom metadata indices will perform better with the filtered HNSW instead. When false, the server will use the filtered HNSW index to filter chunks. When true, the server will perform a full scan over the metadata JSONB column to filter chunks. Default is true. - */ - jsonb_prefilter?: (boolean) | null; /** * All of these field conditions have to match for the chunk to be included in the result set. */ @@ -2720,6 +2716,10 @@ export type SortBySearchType = { */ export type SortOptions = { location_bias?: ((GeoInfoWithBias) | null); + /** + * Recency Bias lets you determine how much of an effect the recency of chunks will have on the search results. If not specified, this defaults to 0.0. We recommend setting this to 1.0 for a gentle reranking of the results, >3.0 for a strong reranking of the results. + */ + recency_bias?: (number) | null; sort_by?: ((QdrantSortBy) | null); /** * Tag weights is a JSON object which can be used to boost the ranking of chunks with certain tags. This is useful for when you want to be able to bias towards chunks with a certain tag on the fly. The keys are the tag names and the values are the weights. diff --git a/frontends/search/src/components/FilterModal.tsx b/frontends/search/src/components/FilterModal.tsx index 24a961b2d8..44e823f4af 100644 --- a/frontends/search/src/components/FilterModal.tsx +++ b/frontends/search/src/components/FilterModal.tsx @@ -1,5 +1,3 @@ -/* eslint-disable @typescript-eslint/no-unsafe-call */ -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ import { Show, For, createSignal, createEffect } from "solid-js"; export interface FieldFilter { @@ -11,7 +9,8 @@ export interface FieldFilter { } | null; radius?: number | null; } | null; - match?: (string | number)[] | null; + match_any?: (string | number)[] | null; + match_all?: (string | number)[] | null; range?: { gte?: number | null; lte?: number | null; @@ -31,20 +30,14 @@ export interface HasIdFilter { tracking_ids: string[] | null; } +export type Filter = FieldFilter | HasIdFilter; + export interface Filters { must: Filter[]; must_not: Filter[]; should: Filter[]; - jsonb_prefilter?: boolean | null; } -export interface FilterItemProps { - initialFilter: Filter; - onFilterChange: (filter: Filter) => void; -} - -export type Filter = FieldFilter | HasIdFilter; - export function filterIsHasIdFilter(filter: Filter): filter is HasIdFilter { return ( filter != null && @@ -65,10 +58,15 @@ export function filterAsFieldFilter(filter: Filter): FieldFilter | null { return filterIsFieldFilter(filter) ? filter : null; } +export interface FilterItemProps { + initialFilter: Filter; + onFilterChange: (filter: Filter) => void; +} + export const FilterItem = (props: FilterItemProps) => { const [curFilter, setCurFilter] = createSignal(props.initialFilter); - let initialTempFilterMode = "match"; + let initialTempFilterMode = "match_any"; let initialTempFilterField = "tag_set"; if (filterIsFieldFilter(props.initialFilter) && props.initialFilter != null) { @@ -127,8 +125,12 @@ export const FilterItem = (props: FilterItemProps) => { lte: filterAsFieldFilter(props.initialFilter)?.date_range?.lte ?? null, }); - const [match, setMatch] = createSignal<(string | number)[] | null>( - filterAsFieldFilter(props.initialFilter)?.match ?? null, + const [matchAny, setMatchAny] = createSignal<(string | number)[] | null>( + filterAsFieldFilter(props.initialFilter)?.match_any ?? null, + ); + + const [matchAll, setMatchAll] = createSignal<(string | number)[] | null>( + filterAsFieldFilter(props.initialFilter)?.match_all ?? null, ); const [idFilterText, setIdFilterText] = createSignal( @@ -139,6 +141,8 @@ export const FilterItem = (props: FilterItemProps) => { createEffect(() => { const changedField = tempFilterField(); + const curMatchAll = + filterAsFieldFilter(props.initialFilter)?.match_all ?? []; if (changedField === "ids") { setCurFilter({ @@ -151,10 +155,11 @@ export const FilterItem = (props: FilterItemProps) => { tracking_ids: idFilterText(), } as HasIdFilter); } else { - setTempFilterMode("match"); + setTempFilterMode( + (curMatchAll?.length ?? 0) > 0 ? "match_all" : "match_any", + ); return; } - setTempFilterMode("has_id_filter"); }); createEffect(() => { @@ -170,31 +175,118 @@ export const FilterItem = (props: FilterItemProps) => { }, radius: location().radius, }, + match_any: null, + match_all: null, + range: null, + date_range: null, + }); + setMatchAll(null); + setMatchAny(null); + setRange({ + gt: null, + lt: null, + gte: null, + lte: null, + }); + setDateRange({ + gt: null, + lt: null, + gte: null, + lte: null, }); } if (changedMode === "range") { setCurFilter({ field: tempFilterField(), + match_any: null, + match_all: null, range: { gt: range().gt, lt: range().lt, gte: range().gte, lte: range().lte, }, + date_range: null, + }); + setMatchAll(null); + setMatchAny(null); + setDateRange({ + gt: null, + lt: null, + gte: null, + lte: null, + }); + setLocation({ + lat: null, + lon: null, + radius: null, }); } - if (changedMode === "match") { + if (changedMode === "match_any") { setCurFilter({ field: tempFilterField(), - match: match(), + match_any: matchAny(), + match_all: null, + range: null, + date_range: null, + }); + setMatchAll(null); + setRange({ + gt: null, + lt: null, + gte: null, + lte: null, + }); + setDateRange({ + gt: null, + lt: null, + gte: null, + lte: null, + }); + setLocation({ + lat: null, + lon: null, + radius: null, + }); + } + + if (changedMode === "match_all") { + console.log("match_all"); + setCurFilter({ + field: tempFilterField(), + match_any: null, + match_all: matchAll(), + range: null, + date_range: null, + } satisfies FieldFilter); + setMatchAny(null); + setRange({ + gt: null, + lt: null, + gte: null, + lte: null, + }); + setDateRange({ + gt: null, + lt: null, + gte: null, + lte: null, + }); + setLocation({ + lat: null, + lon: null, + radius: null, }); } if (changedMode === "date_range") { setCurFilter({ field: tempFilterField(), + match_any: null, + match_all: null, + range: null, date_range: { gt: dateRange().gt, lt: dateRange().lt, @@ -202,6 +294,19 @@ export const FilterItem = (props: FilterItemProps) => { lte: dateRange().lte, }, }); + setMatchAll(null); + setMatchAny(null); + setRange({ + gt: null, + lt: null, + gte: null, + lte: null, + }); + setLocation({ + lat: null, + lon: null, + radius: null, + }); } }); @@ -281,7 +386,15 @@ export const FilterItem = (props: FilterItemProps) => { }} value={tempFilterMode()} > - + {(filter_mode) => { return (