diff --git a/src/collections/collection/index.ts b/src/collections/collection/index.ts index 3fa1108c..c4164352 100644 --- a/src/collections/collection/index.ts +++ b/src/collections/collection/index.ts @@ -14,7 +14,7 @@ import { Iterator } from '../iterator/index.js'; import query, { Query } from '../query/index.js'; import sort, { Sort } from '../sort/index.js'; import tenants, { TenantBase, Tenants } from '../tenants/index.js'; -import { QueryMetadata, QueryProperty, QueryReference } from '../types/index.js'; +import { QueryMetadata, QueryProperty, QueryReference, ReturnVectors } from '../types/index.js'; import { IncludeVector } from '../types/internal.js'; import multiTargetVector, { MultiTargetVector } from '../vectors/multiTargetVector.js'; @@ -55,15 +55,19 @@ export interface Collection { * This iterator keeps a record of the last object that it returned to be used in each subsequent call to Weaviate. * Once the collection is exhausted, the iterator exits. * + * @typeParam I - The vector(s) to include in the response. If using named vectors, pass an array of strings to include only specific vectors. + * @typeParam RV - The vectors(s) to be returned in the response depending on the input in opts.includeVector. * @param {IteratorOptions} opts The options to use when fetching objects from Weaviate. * @returns {Iterator} An iterator over the objects in the collection as an async generator. * * @description If `return_properties` is not provided, all the properties of each object will be * requested from Weaviate except for its vector as this is an expensive operation. Specify `include_vector` - * to request the vector back as well. In addition, if `return_references=None` then none of the references + * to request the vectors back as well. In addition, if `return_references=None` then none of the references * are returned. Use `wvc.QueryReference` to specify which references to return. */ - iterator: (opts?: IteratorOptions) => Iterator; + iterator: , RV extends ReturnVectors>( + opts?: IteratorOptions + ) => Iterator; /** * Use this method to return the total number of objects in the collection. * @@ -95,8 +99,8 @@ export interface Collection { withTenant: (tenant: string | TT) => Collection; } -export type IteratorOptions = { - includeVector?: IncludeVector; +export type IteratorOptions = { + includeVector?: I; returnMetadata?: QueryMetadata; returnProperties?: QueryProperty[]; returnReferences?: QueryReference[]; @@ -146,10 +150,10 @@ const collection = ( sort: sort(), tenants: tenants(connection, capitalizedName, dbVersionSupport), exists: () => new ClassExists(connection).withClassName(capitalizedName).do(), - iterator: (opts?: IteratorOptions) => - new Iterator((limit: number, after?: string) => + iterator: , RV extends ReturnVectors>(opts?: IteratorOptions) => + new Iterator((limit: number, after?: string) => queryCollection - .fetchObjects({ + .fetchObjects({ limit, after, includeVector: opts?.includeVector, diff --git a/src/collections/generate/index.ts b/src/collections/generate/index.ts index 381e29d4..db532b71 100644 --- a/src/collections/generate/index.ts +++ b/src/collections/generate/index.ts @@ -33,7 +33,9 @@ import { GenerativeGroupByReturn, GenerativeReturn, GroupByOptions, + ReturnVectors, } from '../types/index.js'; +import { IncludeVector } from '../types/internal.js'; import { Generate } from './types.js'; class GenerateManager implements Generate { @@ -55,19 +57,19 @@ class GenerateManager implements Generate { ); } - private async parseReply(reply: SearchReply) { + private async parseReply(reply: SearchReply) { const deserialize = await Deserialize.use(this.check.dbVersionSupport); - return deserialize.generate(reply); + return deserialize.generate(reply); } - private async parseGroupByReply( - opts: SearchOptions | GroupByOptions | undefined, + private async parseGroupByReply( + opts: SearchOptions | GroupByOptions | undefined, reply: SearchReply ) { const deserialize = await Deserialize.use(this.check.dbVersionSupport); return Serialize.search.isGroupBy(opts) - ? deserialize.generateGroupBy(reply) - : deserialize.generate(reply); + ? deserialize.generateGroupBy(reply) + : deserialize.generate(reply); } public fetchObjects( @@ -90,21 +92,29 @@ class GenerateManager implements Generate { .then((reply) => this.parseReply(reply)); } - public bm25( + public bm25< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( query: string, generate: GenerateOptions, - opts?: BaseBm25Options - ): Promise>; - public bm25( + opts?: BaseBm25Options + ): Promise>; + public bm25< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( query: string, generate: GenerateOptions, - opts: GroupByBm25Options - ): Promise>; - public bm25( - query: string, - generate: GenerateOptions, - opts?: Bm25Options - ): GenerateReturn { + opts: GroupByBm25Options + ): Promise>; + public bm25< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >(query: string, generate: GenerateOptions, opts?: Bm25Options): GenerateReturn { return Promise.all([ this.check.bm25(opts), this.check.supportForSingleGroupedGenerative(), @@ -121,21 +131,29 @@ class GenerateManager implements Generate { .then((reply) => this.parseGroupByReply(opts, reply)); } - public hybrid( - query: string, - generate: GenerateOptions, - opts?: BaseHybridOptions - ): Promise>; - public hybrid( + public hybrid< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( query: string, generate: GenerateOptions, - opts: GroupByHybridOptions - ): Promise>; - public hybrid( + opts?: BaseHybridOptions + ): Promise>; + public hybrid< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( query: string, generate: GenerateOptions, - opts?: HybridOptions - ): GenerateReturn { + opts: GroupByHybridOptions + ): Promise>; + public hybrid< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >(query: string, generate: GenerateOptions, opts?: HybridOptions): GenerateReturn { return Promise.all([ this.check.hybridSearch(opts), this.check.supportForSingleGroupedGenerative(), @@ -166,21 +184,33 @@ class GenerateManager implements Generate { .then((reply) => this.parseGroupByReply(opts, reply)); } - public nearImage( + public nearImage< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( image: string | Buffer, generate: GenerateOptions, - opts?: BaseNearOptions - ): Promise>; - public nearImage( + opts?: BaseNearOptions + ): Promise>; + public nearImage< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( image: string | Buffer, generate: GenerateOptions, - opts: GroupByNearOptions - ): Promise>; - public nearImage( + opts: GroupByNearOptions + ): Promise>; + public nearImage< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( image: string | Buffer, generate: GenerateOptions, - opts?: NearOptions - ): GenerateReturn { + opts?: NearOptions + ): GenerateReturn { return Promise.all([ this.check.nearSearch(opts), this.check.supportForSingleGroupedGenerative(), @@ -204,21 +234,29 @@ class GenerateManager implements Generate { .then((reply) => this.parseGroupByReply(opts, reply)); } - public nearObject( - id: string, - generate: GenerateOptions, - opts?: BaseNearOptions - ): Promise>; - public nearObject( + public nearObject< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( id: string, generate: GenerateOptions, - opts: GroupByNearOptions - ): Promise>; - public nearObject( + opts?: BaseNearOptions + ): Promise>; + public nearObject< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( id: string, generate: GenerateOptions, - opts?: NearOptions - ): GenerateReturn { + opts: GroupByNearOptions + ): Promise>; + public nearObject< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >(id: string, generate: GenerateOptions, opts?: NearOptions): GenerateReturn { return Promise.all([ this.check.nearSearch(opts), this.check.supportForSingleGroupedGenerative(), @@ -242,21 +280,33 @@ class GenerateManager implements Generate { .then((reply) => this.parseGroupByReply(opts, reply)); } - public nearText( + public nearText< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( query: string | string[], generate: GenerateOptions, - opts?: BaseNearTextOptions - ): Promise>; - public nearText( + opts?: BaseNearTextOptions + ): Promise>; + public nearText< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( query: string | string[], generate: GenerateOptions, - opts: GroupByNearTextOptions - ): Promise>; - public nearText( + opts: GroupByNearTextOptions + ): Promise>; + public nearText< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( query: string | string[], generate: GenerateOptions, - opts?: NearOptions - ): GenerateReturn { + opts?: NearOptions + ): GenerateReturn { return Promise.all([ this.check.nearSearch(opts), this.check.supportForSingleGroupedGenerative(), @@ -280,21 +330,33 @@ class GenerateManager implements Generate { .then((reply) => this.parseGroupByReply(opts, reply)); } - public nearVector( + public nearVector< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( vector: number[], generate: GenerateOptions, - opts?: BaseNearOptions - ): Promise>; - public nearVector( + opts?: BaseNearOptions + ): Promise>; + public nearVector< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( vector: number[], generate: GenerateOptions, - opts: GroupByNearOptions - ): Promise>; - public nearVector( + opts: GroupByNearOptions + ): Promise>; + public nearVector< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( vector: number[], generate: GenerateOptions, - opts?: NearOptions - ): GenerateReturn { + opts?: NearOptions + ): GenerateReturn { return Promise.all([ this.check.nearVector(vector, opts), this.check.supportForSingleGroupedGenerative(), @@ -325,24 +387,36 @@ class GenerateManager implements Generate { .then((reply) => this.parseGroupByReply(opts, reply)); } - public nearMedia( + public nearMedia< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( media: string | Buffer, type: NearMediaType, generate: GenerateOptions, - opts?: BaseNearOptions - ): Promise>; - public nearMedia( + opts?: BaseNearOptions + ): Promise>; + public nearMedia< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( media: string | Buffer, type: NearMediaType, generate: GenerateOptions, - opts: GroupByNearOptions - ): Promise>; - public nearMedia( + opts: GroupByNearOptions + ): Promise>; + public nearMedia< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( media: string | Buffer, type: NearMediaType, generate: GenerateOptions, - opts?: NearOptions - ): GenerateReturn { + opts?: NearOptions + ): GenerateReturn { return Promise.all([ this.check.nearSearch(opts), this.check.supportForSingleGroupedGenerative(), diff --git a/src/collections/generate/types.ts b/src/collections/generate/types.ts index f29160ec..b9022f7c 100644 --- a/src/collections/generate/types.ts +++ b/src/collections/generate/types.ts @@ -21,7 +21,9 @@ import { GenerativeConfigRuntime, GenerativeGroupByReturn, GenerativeReturn, + ReturnVectors, } from '../types/index.js'; +import { IncludeVector } from '../types/internal.js'; interface Bm25 { /** @@ -36,11 +38,15 @@ interface Bm25 { * @param {BaseBm25Options} [opts] - The available options for performing the BM25 search. * @return {Promise>} - The results of the search including the generated data. */ - bm25( + bm25< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( query: string, generate: GenerateOptions, - opts?: BaseBm25Options - ): Promise>; + opts?: BaseBm25Options + ): Promise>; /** * Perform retrieval-augmented generation (RaG) on the results of a keyword-based BM25 search of objects in this collection. * @@ -53,11 +59,15 @@ interface Bm25 { * @param {GroupByBm25Options} opts - The available options for performing the BM25 search. * @return {Promise>} - The results of the search including the generated data grouped by the specified properties. */ - bm25( + bm25< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( query: string, generate: GenerateOptions, - opts: GroupByBm25Options - ): Promise>; + opts: GroupByBm25Options + ): Promise>; /** * Perform retrieval-augmented generation (RaG) on the results of a keyword-based BM25 search of objects in this collection. * @@ -70,11 +80,15 @@ interface Bm25 { * @param {Bm25Options} [opts] - The available options for performing the BM25 search. * @return {GenerateReturn} - The results of the search including the generated data. */ - bm25( + bm25< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( query: string, generate: GenerateOptions, - opts?: Bm25Options - ): GenerateReturn; + opts?: Bm25Options + ): GenerateReturn; } interface Hybrid { @@ -90,11 +104,15 @@ interface Hybrid { * @param {BaseHybridOptions} [opts] - The available options for performing the hybrid search. * @return {Promise>} - The results of the search including the generated data. */ - hybrid( + hybrid< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( query: string, generate: GenerateOptions, - opts?: BaseHybridOptions - ): Promise>; + opts?: BaseHybridOptions + ): Promise>; /** * Perform retrieval-augmented generation (RaG) on the results of an object search in this collection using the hybrid algorithm blending keyword-based BM25 and vector-based similarity. * @@ -107,11 +125,15 @@ interface Hybrid { * @param {GroupByHybridOptions} opts - The available options for performing the hybrid search. * @return {Promise>} - The results of the search including the generated data grouped by the specified properties. */ - hybrid( + hybrid< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( query: string, generate: GenerateOptions, - opts: GroupByHybridOptions - ): Promise>; + opts: GroupByHybridOptions + ): Promise>; /** * Perform retrieval-augmented generation (RaG) on the results of an object search in this collection using the hybrid algorithm blending keyword-based BM25 and vector-based similarity. * @@ -124,11 +146,15 @@ interface Hybrid { * @param {HybridOptions} [opts] - The available options for performing the hybrid search. * @return {GenerateReturn} - The results of the search including the generated data. */ - hybrid( + hybrid< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( query: string, generate: GenerateOptions, - opts?: HybridOptions - ): GenerateReturn; + opts?: HybridOptions + ): GenerateReturn; } interface NearMedia { @@ -147,12 +173,16 @@ interface NearMedia { * @param {BaseNearOptions} [opts] - The available options for performing the near-media search. * @return {Promise>} - The results of the search including the generated data. */ - nearMedia( + nearMedia< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( media: string | Buffer, type: NearMediaType, generate: GenerateOptions, - opts?: BaseNearOptions - ): Promise>; + opts?: BaseNearOptions + ): Promise>; /** * Perform retrieval-augmented generation (RaG) on the results of a by-audio object search in this collection using an audio-capable vectorization module and vector-based similarity search. * @@ -168,12 +198,16 @@ interface NearMedia { * @param {GroupByNearOptions} opts - The available options for performing the near-media search. * @return {Promise>} - The results of the search including the generated data grouped by the specified properties. */ - nearMedia( + nearMedia< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( media: string | Buffer, type: NearMediaType, generate: GenerateOptions, - opts: GroupByNearOptions - ): Promise>; + opts: GroupByNearOptions + ): Promise>; /** * Perform retrieval-augmented generation (RaG) on the results of a by-audio object search in this collection using an audio-capable vectorization module and vector-based similarity search. * @@ -189,12 +223,16 @@ interface NearMedia { * @param {NearOptions} [opts] - The available options for performing the near-media search. * @return {GenerateReturn} - The results of the search including the generated data. */ - nearMedia( + nearMedia< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( media: string | Buffer, type: NearMediaType, generate: GenerateOptions, - opts?: NearOptions - ): GenerateReturn; + opts?: NearOptions + ): GenerateReturn; } interface NearObject { @@ -210,11 +248,15 @@ interface NearObject { * @param {BaseNearOptions} [opts] - The available options for performing the near-object search. * @return {Promise>} - The results of the search including the generated data. */ - nearObject( + nearObject< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( id: string, generate: GenerateOptions, - opts?: BaseNearOptions - ): Promise>; + opts?: BaseNearOptions + ): Promise>; /** * Perform retrieval-augmented generation (RaG) on the results of a by-object object search in this collection using a vector-based similarity search. * @@ -227,11 +269,15 @@ interface NearObject { * @param {GroupByNearOptions} opts - The available options for performing the near-object search. * @return {Promise>} - The results of the search including the generated data grouped by the specified properties. */ - nearObject( + nearObject< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( id: string, generate: GenerateOptions, - opts: GroupByNearOptions - ): Promise>; + opts: GroupByNearOptions + ): Promise>; /** * Perform retrieval-augmented generation (RaG) on the results of a by-object object search in this collection using a vector-based similarity search. * @@ -244,11 +290,15 @@ interface NearObject { * @param {NearOptions} [opts] - The available options for performing the near-object search. * @return {GenerateReturn} - The results of the search including the generated data. */ - nearObject( + nearObject< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( id: string, generate: GenerateOptions, - opts?: NearOptions - ): GenerateReturn; + opts?: NearOptions + ): GenerateReturn; } interface NearText { @@ -266,11 +316,15 @@ interface NearText { * @param {BaseNearTextOptions} [opts] - The available options for performing the near-text search. * @return {Promise>} - The results of the search including the generated data. */ - nearText( + nearText< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( query: string | string[], generate: GenerateOptions, - opts?: BaseNearTextOptions - ): Promise>; + opts?: BaseNearTextOptions + ): Promise>; /** * Perform retrieval-augmented generation (RaG) on the results of a by-image object search in this collection using the image-capable vectorization module and vector-based similarity search. * @@ -285,11 +339,15 @@ interface NearText { * @param {GroupByNearTextOptions} opts - The available options for performing the near-text search. * @return {Promise>} - The results of the search including the generated data grouped by the specified properties. */ - nearText( + nearText< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( query: string | string[], generate: GenerateOptions, - opts: GroupByNearTextOptions - ): Promise>; + opts: GroupByNearTextOptions + ): Promise>; /** * Perform retrieval-augmented generation (RaG) on the results of a by-image object search in this collection using the image-capable vectorization module and vector-based similarity search. * @@ -304,11 +362,15 @@ interface NearText { * @param {NearTextOptions} [opts] - The available options for performing the near-text search. * @return {GenerateReturn} - The results of the search including the generated data. */ - nearText( + nearText< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( query: string | string[], generate: GenerateOptions, - opts?: NearTextOptions - ): GenerateReturn; + opts?: NearTextOptions + ): GenerateReturn; } interface NearVector { @@ -324,11 +386,15 @@ interface NearVector { * @param {BaseNearOptions} [opts] - The available options for performing the near-vector search. * @return {Promise>} - The results of the search including the generated data. */ - nearVector( + nearVector< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( vector: NearVectorInputType, generate: GenerateOptions, - opts?: BaseNearOptions - ): Promise>; + opts?: BaseNearOptions + ): Promise>; /** * Perform retrieval-augmented generation (RaG) on the results of a by-vector object search in this collection using vector-based similarity search. * @@ -341,11 +407,15 @@ interface NearVector { * @param {GroupByNearOptions} opts - The available options for performing the near-vector search. * @return {Promise>} - The results of the search including the generated data grouped by the specified properties. */ - nearVector( + nearVector< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( vector: NearVectorInputType, generate: GenerateOptions, - opts: GroupByNearOptions - ): Promise>; + opts: GroupByNearOptions + ): Promise>; /** * Perform retrieval-augmented generation (RaG) on the results of a by-vector object search in this collection using vector-based similarity search. * @@ -358,11 +428,15 @@ interface NearVector { * @param {NearOptions} [opts] - The available options for performing the near-vector search. * @return {GenerateReturn} - The results of the search including the generated data. */ - nearVector( + nearVector< + I extends IncludeVector, + RV extends ReturnVectors, + C extends GenerativeConfigRuntime | undefined = undefined + >( vector: NearVectorInputType, generate: GenerateOptions, - opts?: NearOptions - ): GenerateReturn; + opts?: NearOptions + ): GenerateReturn; } export interface Generate diff --git a/src/collections/query/check.ts b/src/collections/query/check.ts index c090cadc..8cc1230f 100644 --- a/src/collections/query/check.ts +++ b/src/collections/query/check.ts @@ -40,7 +40,7 @@ export class Check { private getSearcher = () => this.connection.search(this.name, this.consistencyLevel, this.tenant); - private checkSupportForNamedVectors = async (opts?: BaseNearOptions) => { + private checkSupportForNamedVectors = async (opts?: BaseNearOptions) => { if (!Serialize.isNamedVectors(opts)) return; const check = await this.dbVersionSupport.supportsNamedVectors(); if (!check.supports) throw new WeaviateUnsupportedFeatureError(check.message); @@ -48,20 +48,22 @@ export class Check { private checkSupportForBm25AndHybridGroupByQueries = async ( query: 'Bm25' | 'Hybrid', - opts?: SearchOptions | GroupByOptions + opts?: SearchOptions | GroupByOptions ) => { if (!Serialize.search.isGroupBy(opts)) return; const check = await this.dbVersionSupport.supportsBm25AndHybridGroupByQueries(); if (!check.supports) throw new WeaviateUnsupportedFeatureError(check.message(query)); }; - private checkSupportForHybridNearTextAndNearVectorSubSearches = async (opts?: HybridOptions) => { + private checkSupportForHybridNearTextAndNearVectorSubSearches = async ( + opts?: HybridOptions + ) => { if (opts?.vector === undefined || Array.isArray(opts.vector)) return; const check = await this.dbVersionSupport.supportsHybridNearTextAndNearVectorSubsearchQueries(); if (!check.supports) throw new WeaviateUnsupportedFeatureError(check.message); }; - private checkSupportForMultiTargetSearch = async (opts?: BaseNearOptions) => { + private checkSupportForMultiTargetSearch = async (opts?: BaseNearOptions) => { if (!Serialize.isMultiTarget(opts)) return false; const check = await this.dbVersionSupport.supportsMultiTargetVectorSearch(); if (!check.supports) throw new WeaviateUnsupportedFeatureError(check.message); @@ -79,7 +81,7 @@ export class Check { return check.supports; }; - private checkSupportForMultiWeightPerTargetSearch = async (opts?: BaseNearOptions) => { + private checkSupportForMultiWeightPerTargetSearch = async (opts?: BaseNearOptions) => { if (!Serialize.isMultiWeightPerTarget(opts)) return false; const check = await this.dbVersionSupport.supportsMultiWeightsPerTargetSearch(); if (!check.supports) throw new WeaviateUnsupportedFeatureError(check.message); @@ -119,7 +121,7 @@ export class Check { return check.supports; }; - public nearSearch = (opts?: BaseNearOptions) => { + public nearSearch = (opts?: BaseNearOptions) => { return Promise.all([ this.getSearcher(), this.checkSupportForMultiTargetSearch(opts), @@ -132,7 +134,7 @@ export class Check { }); }; - public nearVector = (vec: NearVectorInputType, opts?: BaseNearOptions) => { + public nearVector = (vec: NearVectorInputType, opts?: BaseNearOptions) => { return Promise.all([ this.getSearcher(), this.checkSupportForMultiTargetSearch(opts), @@ -164,7 +166,7 @@ export class Check { ); }; - public hybridSearch = (opts?: BaseHybridOptions) => { + public hybridSearch = (opts?: BaseHybridOptions) => { return Promise.all([ this.getSearcher(), this.checkSupportForMultiTargetSearch(opts), @@ -198,19 +200,19 @@ export class Check { ); }; - public fetchObjects = (opts?: FetchObjectsOptions) => { + public fetchObjects = (opts?: FetchObjectsOptions) => { return Promise.all([this.getSearcher(), this.checkSupportForNamedVectors(opts)]).then(([search]) => { return { search }; }); }; - public fetchObjectById = (opts?: FetchObjectByIdOptions) => { + public fetchObjectById = (opts?: FetchObjectByIdOptions) => { return Promise.all([this.getSearcher(), this.checkSupportForNamedVectors(opts)]).then(([search]) => { return { search }; }); }; - public bm25 = (opts?: BaseBm25Options) => { + public bm25 = (opts?: BaseBm25Options) => { return Promise.all([ this.getSearcher(), this.checkSupportForNamedVectors(opts), diff --git a/src/collections/query/index.ts b/src/collections/query/index.ts index 1dda49bf..81581502 100644 --- a/src/collections/query/index.ts +++ b/src/collections/query/index.ts @@ -8,9 +8,16 @@ import { DbVersionSupport } from '../../utils/dbVersion.js'; import { SearchReply } from '../../proto/v1/search_get.js'; import { Deserialize } from '../deserialize/index.js'; import { Serialize } from '../serialize/index.js'; -import { GroupByOptions, GroupByReturn, WeaviateObject, WeaviateReturn } from '../types/index.js'; +import { + GroupByOptions, + GroupByReturn, + ReturnVectors, + WeaviateObject, + WeaviateReturn, +} from '../types/index.js'; import { WeaviateInvalidInputError } from '../../errors.js'; +import { IncludeVector } from '../types/internal.js'; import { Check } from './check.js'; import { BaseBm25Options, @@ -53,51 +60,71 @@ class QueryManager implements Query { ); } - private async parseReply(reply: SearchReply) { + private async parseReply(reply: SearchReply) { const deserialize = await Deserialize.use(this.check.dbVersionSupport); - return deserialize.query(reply); + return deserialize.query(reply); } - private async parseGroupByReply( - opts: SearchOptions | GroupByOptions | undefined, + private async parseGroupByReply( + opts: SearchOptions | GroupByOptions | undefined, reply: SearchReply ) { const deserialize = await Deserialize.use(this.check.dbVersionSupport); return Serialize.search.isGroupBy(opts) - ? deserialize.queryGroupBy(reply) - : deserialize.query(reply); + ? deserialize.queryGroupBy(reply) + : deserialize.query(reply); } - public fetchObjectById( + public fetchObjectById, RV extends ReturnVectors>( id: string, - opts?: FetchObjectByIdOptions - ): Promise | null> { + opts?: FetchObjectByIdOptions + ): Promise | null> { return this.check .fetchObjectById(opts) .then(({ search }) => search.withFetch(Serialize.search.fetchObjectById({ id, ...opts }))) - .then((reply) => this.parseReply(reply)) + .then((reply) => this.parseReply(reply)) .then((ret) => (ret.objects.length === 1 ? ret.objects[0] : null)); } - public fetchObjects(opts?: FetchObjectsOptions): Promise> { + public fetchObjects, RV extends ReturnVectors>( + opts?: FetchObjectsOptions + ): Promise> { return this.check .fetchObjects(opts) .then(({ search }) => search.withFetch(Serialize.search.fetchObjects(opts))) .then((reply) => this.parseReply(reply)); } - public bm25(query: string, opts?: BaseBm25Options): Promise>; - public bm25(query: string, opts: GroupByBm25Options): Promise>; - public bm25(query: string, opts?: Bm25Options): QueryReturn { + public bm25, RV extends ReturnVectors>( + query: string, + opts?: BaseBm25Options + ): Promise>; + public bm25, RV extends ReturnVectors>( + query: string, + opts: GroupByBm25Options + ): Promise>; + public bm25, RV extends ReturnVectors>( + query: string, + opts?: Bm25Options + ): QueryReturn { return this.check .bm25(opts) .then(({ search }) => search.withBm25(Serialize.search.bm25(query, opts))) .then((reply) => this.parseGroupByReply(opts, reply)); } - public hybrid(query: string, opts?: BaseHybridOptions): Promise>; - public hybrid(query: string, opts: GroupByHybridOptions): Promise>; - public hybrid(query: string, opts?: HybridOptions): QueryReturn { + public hybrid, RV extends ReturnVectors>( + query: string, + opts?: BaseHybridOptions + ): Promise>; + public hybrid, RV extends ReturnVectors>( + query: string, + opts: GroupByHybridOptions + ): Promise>; + public hybrid, RV extends ReturnVectors>( + query: string, + opts?: HybridOptions + ): QueryReturn { return this.check .hybridSearch(opts) .then( @@ -125,9 +152,18 @@ class QueryManager implements Query { .then((reply) => this.parseGroupByReply(opts, reply)); } - public nearImage(image: string | Buffer, opts?: BaseNearOptions): Promise>; - public nearImage(image: string | Buffer, opts: GroupByNearOptions): Promise>; - public nearImage(image: string | Buffer, opts?: NearOptions): QueryReturn { + public nearImage, RV extends ReturnVectors>( + image: string | Buffer, + opts?: BaseNearOptions + ): Promise>; + public nearImage, RV extends ReturnVectors>( + image: string | Buffer, + opts: GroupByNearOptions + ): Promise>; + public nearImage, RV extends ReturnVectors>( + image: string | Buffer, + opts?: NearOptions + ): QueryReturn { return this.check .nearSearch(opts) .then(({ search, supportsTargets, supportsWeightsForTargets }) => { @@ -147,17 +183,21 @@ class QueryManager implements Query { .then((reply) => this.parseGroupByReply(opts, reply)); } - public nearMedia( + public nearMedia, RV extends ReturnVectors>( + media: string | Buffer, + type: NearMediaType, + opts?: BaseNearOptions + ): Promise>; + public nearMedia, RV extends ReturnVectors>( media: string | Buffer, type: NearMediaType, - opts?: BaseNearOptions - ): Promise>; - public nearMedia( + opts: GroupByNearOptions + ): Promise>; + public nearMedia, RV extends ReturnVectors>( media: string | Buffer, type: NearMediaType, - opts: GroupByNearOptions - ): Promise>; - public nearMedia(media: string | Buffer, type: NearMediaType, opts?: NearOptions): QueryReturn { + opts?: NearOptions + ): QueryReturn { return this.check .nearSearch(opts) .then(({ search, supportsTargets, supportsWeightsForTargets }) => { @@ -197,9 +237,18 @@ class QueryManager implements Query { .then((reply) => this.parseGroupByReply(opts, reply)); } - public nearObject(id: string, opts?: BaseNearOptions): Promise>; - public nearObject(id: string, opts: GroupByNearOptions): Promise>; - public nearObject(id: string, opts?: NearOptions): QueryReturn { + public nearObject, RV extends ReturnVectors>( + id: string, + opts?: BaseNearOptions + ): Promise>; + public nearObject, RV extends ReturnVectors>( + id: string, + opts: GroupByNearOptions + ): Promise>; + public nearObject, RV extends ReturnVectors>( + id: string, + opts?: NearOptions + ): QueryReturn { return this.check .nearSearch(opts) .then(({ search, supportsTargets, supportsWeightsForTargets }) => ({ @@ -217,9 +266,18 @@ class QueryManager implements Query { .then((reply) => this.parseGroupByReply(opts, reply)); } - public nearText(query: string | string[], opts?: BaseNearTextOptions): Promise>; - public nearText(query: string | string[], opts: GroupByNearTextOptions): Promise>; - public nearText(query: string | string[], opts?: NearTextOptions): QueryReturn { + public nearText, RV extends ReturnVectors>( + query: string | string[], + opts?: BaseNearTextOptions + ): Promise>; + public nearText, RV extends ReturnVectors>( + query: string | string[], + opts: GroupByNearTextOptions + ): Promise>; + public nearText, RV extends ReturnVectors>( + query: string | string[], + opts?: NearTextOptions + ): QueryReturn { return this.check .nearSearch(opts) .then(({ search, supportsTargets, supportsWeightsForTargets }) => ({ @@ -237,12 +295,18 @@ class QueryManager implements Query { .then((reply) => this.parseGroupByReply(opts, reply)); } - public nearVector(vector: NearVectorInputType, opts?: BaseNearOptions): Promise>; - public nearVector( + public nearVector, RV extends ReturnVectors>( + vector: NearVectorInputType, + opts?: BaseNearOptions + ): Promise>; + public nearVector, RV extends ReturnVectors>( + vector: NearVectorInputType, + opts: GroupByNearOptions + ): Promise>; + public nearVector, RV extends ReturnVectors>( vector: NearVectorInputType, - opts: GroupByNearOptions - ): Promise>; - public nearVector(vector: NearVectorInputType, opts?: NearOptions): QueryReturn { + opts?: NearOptions + ): QueryReturn { return this.check .nearVector(vector, opts) .then( diff --git a/src/collections/query/types.ts b/src/collections/query/types.ts index 6255e03c..0cbf3580 100644 --- a/src/collections/query/types.ts +++ b/src/collections/query/types.ts @@ -1,5 +1,5 @@ import { FilterValue } from '../filters/index.js'; -import { MultiTargetVectorJoin } from '../index.js'; +import { MultiTargetVectorJoin, ReturnVectors } from '../index.js'; import { Sorting } from '../sort/classes.js'; import { GroupByOptions, @@ -14,9 +14,9 @@ import { import { IncludeVector, PrimitiveKeys } from '../types/internal.js'; /** Options available in the `query.fetchObjectById` method */ -export type FetchObjectByIdOptions = { +export type FetchObjectByIdOptions = { /** Whether to include the vector of the object in the response. If using named vectors, pass an array of strings to include only specific vectors. */ - includeVector?: IncludeVector; + includeVector?: I; /** * Which properties of the object to return. Can be primitive, in which case specify their names, or nested, in which case * use the QueryNested type. If not specified, all properties are returned. @@ -27,7 +27,7 @@ export type FetchObjectByIdOptions = { }; /** Options available in the `query.fetchObjects` method */ -export type FetchObjectsOptions = { +export type FetchObjectsOptions = { /** How many objects to return in the query */ limit?: number; /** How many objects to skip in the query. Incompatible with the `after` cursor */ @@ -39,7 +39,7 @@ export type FetchObjectsOptions = { /** The sorting to be applied to the query. Use `weaviate.sort.*` to create sorting */ sort?: Sorting; /** Whether to include the vector of the object in the response. If using named vectors, pass an array of strings to include only specific vectors. */ - includeVector?: IncludeVector; + includeVector?: I; /** Which metadata of the object to return. If not specified, no metadata is returned. */ returnMetadata?: QueryMetadata; /** @@ -52,7 +52,7 @@ export type FetchObjectsOptions = { }; /** Base options available to all the query methods that involve searching. */ -export type SearchOptions = { +export type SearchOptions = { /** How many objects to return in the query */ limit?: number; /** How many objects to skip in the query. Incompatible with the `after` cursor */ @@ -64,7 +64,7 @@ export type SearchOptions = { /** How to rerank the query results. Requires a configured [reranking](https://weaviate.io/developers/weaviate/concepts/reranking) module. */ rerank?: RerankOptions; /** Whether to include the vector of the object in the response. If using named vectors, pass an array of strings to include only specific vectors. */ - includeVector?: IncludeVector; + includeVector?: I; /** Which metadata of the object to return. If not specified, no metadata is returned. */ returnMetadata?: QueryMetadata; /** @@ -90,16 +90,16 @@ export type Bm25SearchOptions = { }; /** Base options available in the `query.bm25` method */ -export type BaseBm25Options = SearchOptions & Bm25SearchOptions; +export type BaseBm25Options = SearchOptions & Bm25SearchOptions; /** Options available in the `query.bm25` method when specifying the `groupBy` parameter. */ -export type GroupByBm25Options = BaseBm25Options & { +export type GroupByBm25Options = BaseBm25Options & { /** The group by options to apply to the search. */ groupBy: GroupByOptions; }; /** Options available in the `query.bm25` method */ -export type Bm25Options = BaseBm25Options | GroupByBm25Options | undefined; +export type Bm25Options = BaseBm25Options | GroupByBm25Options | undefined; /** Options available to the hybrid search type only */ export type HybridSearchOptions = { @@ -118,7 +118,7 @@ export type HybridSearchOptions = { }; /** Base options available in the `query.hybrid` method */ -export type BaseHybridOptions = SearchOptions & HybridSearchOptions; +export type BaseHybridOptions = SearchOptions & HybridSearchOptions; export type HybridSubSearchBase = { certainty?: number; @@ -136,13 +136,13 @@ export type HybridNearVectorSubSearch = HybridSubSearchBase & { }; /** Options available in the `query.hybrid` method when specifying the `groupBy` parameter. */ -export type GroupByHybridOptions = BaseHybridOptions & { +export type GroupByHybridOptions = BaseHybridOptions & { /** The group by options to apply to the search. */ groupBy: GroupByOptions; }; /** Options available in the `query.hybrid` method */ -export type HybridOptions = BaseHybridOptions | GroupByHybridOptions | undefined; +export type HybridOptions = BaseHybridOptions | GroupByHybridOptions | undefined; export type NearSearchOptions = { /** The minimum similarity score to return. Incompatible with the `distance` param. */ @@ -154,10 +154,10 @@ export type NearSearchOptions = { }; /** Base options for the near search queries. */ -export type BaseNearOptions = SearchOptions & NearSearchOptions; +export type BaseNearOptions = SearchOptions & NearSearchOptions; /** Options available in the near search queries when specifying the `groupBy` parameter. */ -export type GroupByNearOptions = BaseNearOptions & { +export type GroupByNearOptions = BaseNearOptions & { /** The group by options to apply to the search. */ groupBy: GroupByOptions; }; @@ -170,13 +170,13 @@ export type MoveOptions = { }; /** Base options for the `query.nearText` method. */ -export type BaseNearTextOptions = BaseNearOptions & { +export type BaseNearTextOptions = BaseNearOptions & { moveTo?: MoveOptions; moveAway?: MoveOptions; }; /** Options available in the near text search queries when specifying the `groupBy` parameter. */ -export type GroupByNearTextOptions = BaseNearTextOptions & { +export type GroupByNearTextOptions = BaseNearTextOptions & { groupBy: GroupByOptions; }; @@ -227,11 +227,16 @@ interface Bm25 { * * This overload is for performing a search without the `groupBy` param. * + * @typeParam I - The vector(s) to include in the response. If using named vectors, pass an array of strings to include only specific vectors. + * @typeParam RV - The vectors(s) to be returned in the response depending on the input in opts.includeVector. * @param {string} query - The query to search for. - * @param {BaseBm25Options} [opts] - The available options for the search excluding the `groupBy` param. - * @returns {Promise>} - The result of the search within the fetched collection. + * @param {BaseBm25Options} [opts] - The available options for the search excluding the `groupBy` param. + * @returns {Promise>>} - The result of the search within the fetched collection. */ - bm25(query: string, opts?: BaseBm25Options): Promise>; + bm25, RV extends ReturnVectors>( + query: string, + opts?: BaseBm25Options + ): Promise>; /** * Search for objects in this collection using the keyword-based BM25 algorithm. * @@ -239,11 +244,16 @@ interface Bm25 { * * This overload is for performing a search with the `groupBy` param. * + * @typeParam I - The vector(s) to include in the response. If using named vectors, pass an array of strings to include only specific vectors. + * @typeParam RV - The vectors(s) to be returned in the response depending on the input in opts.includeVector. * @param {string} query - The query to search for. - * @param {GroupByBm25Options} opts - The available options for the search including the `groupBy` param. + * @param {GroupByBm25Options} opts - The available options for the search including the `groupBy` param. * @returns {Promise>} - The result of the search within the fetched collection. */ - bm25(query: string, opts: GroupByBm25Options): Promise>; + bm25, RV extends ReturnVectors>( + query: string, + opts: GroupByBm25Options + ): Promise>; /** * Search for objects in this collection using the keyword-based BM25 algorithm. * @@ -251,11 +261,16 @@ interface Bm25 { * * This overload is for performing a search with a programmatically defined `opts` param. * + * @typeParam I - The vector(s) to include in the response. If using named vectors, pass an array of strings to include only specific vectors. + * @typeParam RV - The vectors(s) to be returned in the response depending on the input in opts.includeVector. * @param {string} query - The query to search for. * @param {Bm25Options} [opts] - The available options for the search including the `groupBy` param. * @returns {Promise>} - The result of the search within the fetched collection. */ - bm25(query: string, opts?: Bm25Options): QueryReturn; + bm25, RV extends ReturnVectors>( + query: string, + opts?: Bm25Options + ): QueryReturn; } interface Hybrid { @@ -266,11 +281,16 @@ interface Hybrid { * * This overload is for performing a search without the `groupBy` param. * + * @typeParam I - The vector(s) to include in the response. If using named vectors, pass an array of strings to include only specific vectors. + * @typeParam RV - The vectors(s) to be returned in the response depending on the input in opts.includeVector. * @param {string} query - The query to search for in the BM25 keyword search.. * @param {BaseHybridOptions} [opts] - The available options for the search excluding the `groupBy` param. * @returns {Promise>} - The result of the search within the fetched collection. */ - hybrid(query: string, opts?: BaseHybridOptions): Promise>; + hybrid, RV extends ReturnVectors>( + query: string, + opts?: BaseHybridOptions + ): Promise>; /** * Search for objects in this collection using the hybrid algorithm blending keyword-based BM25 and vector-based similarity. * @@ -278,11 +298,16 @@ interface Hybrid { * * This overload is for performing a search with the `groupBy` param. * + * @typeParam I - The vector(s) to include in the response. If using named vectors, pass an array of strings to include only specific vectors. + * @typeParam RV - The vectors(s) to be returned in the response depending on the input in opts.includeVector. * @param {string} query - The query to search for in the BM25 keyword search.. * @param {GroupByHybridOptions} opts - The available options for the search including the `groupBy` param. * @returns {Promise>} - The result of the search within the fetched collection. */ - hybrid(query: string, opts: GroupByHybridOptions): Promise>; + hybrid, RV extends ReturnVectors>( + query: string, + opts: GroupByHybridOptions + ): Promise>; /** * Search for objects in this collection using the hybrid algorithm blending keyword-based BM25 and vector-based similarity. * @@ -294,7 +319,10 @@ interface Hybrid { * @param {HybridOptions} [opts] - The available options for the search including the `groupBy` param. * @returns {Promise>} - The result of the search within the fetched collection. */ - hybrid(query: string, opts?: HybridOptions): QueryReturn; + hybrid, RV extends ReturnVectors>( + query: string, + opts?: HybridOptions + ): QueryReturn; } interface NearImage { @@ -311,7 +339,10 @@ interface NearImage { * @param {BaseNearOptions} [opts] - The available options for the search excluding the `groupBy` param. * @returns {Promise>} - The result of the search within the fetched collection. */ - nearImage(image: string | Buffer, opts?: BaseNearOptions): Promise>; + nearImage, RV extends ReturnVectors>( + image: string | Buffer, + opts?: BaseNearOptions + ): Promise>; /** * Search for objects by image in this collection using an image-capable vectorization module and vector-based similarity search. * You must have an image-capable vectorization module installed in order to use this method, @@ -325,7 +356,10 @@ interface NearImage { * @param {GroupByNearOptions} opts - The available options for the search including the `groupBy` param. * @returns {Promise>} - The group by result of the search within the fetched collection. */ - nearImage(image: string | Buffer, opts: GroupByNearOptions): Promise>; + nearImage, RV extends ReturnVectors>( + image: string | Buffer, + opts: GroupByNearOptions + ): Promise>; /** * Search for objects by image in this collection using an image-capable vectorization module and vector-based similarity search. * You must have an image-capable vectorization module installed in order to use this method, @@ -339,7 +373,10 @@ interface NearImage { * @param {NearOptions} [opts] - The available options for the search. * @returns {QueryReturn} - The result of the search within the fetched collection. */ - nearImage(image: string | Buffer, opts?: NearOptions): QueryReturn; + nearImage, RV extends ReturnVectors>( + image: string | Buffer, + opts?: NearOptions + ): QueryReturn; } interface NearMedia { @@ -356,11 +393,11 @@ interface NearMedia { * @param {BaseNearOptions} [opts] - The available options for the search excluding the `groupBy` param. * @returns {Promise>} - The result of the search within the fetched collection. */ - nearMedia( + nearMedia, RV extends ReturnVectors>( media: string | Buffer, type: NearMediaType, - opts?: BaseNearOptions - ): Promise>; + opts?: BaseNearOptions + ): Promise>; /** * Search for objects by image in this collection using an image-capable vectorization module and vector-based similarity search. * You must have a multi-media-capable vectorization module installed in order to use this method, e.g. `multi2vec-bind` or `multi2vec-palm`. @@ -374,11 +411,11 @@ interface NearMedia { * @param {GroupByNearOptions} opts - The available options for the search including the `groupBy` param. * @returns {Promise>} - The group by result of the search within the fetched collection. */ - nearMedia( + nearMedia, RV extends ReturnVectors>( media: string | Buffer, type: NearMediaType, - opts: GroupByNearOptions - ): Promise>; + opts: GroupByNearOptions + ): Promise>; /** * Search for objects by image in this collection using an image-capable vectorization module and vector-based similarity search. * You must have a multi-media-capable vectorization module installed in order to use this method, e.g. `multi2vec-bind` or `multi2vec-palm`. @@ -392,7 +429,11 @@ interface NearMedia { * @param {NearOptions} [opts] - The available options for the search. * @returns {QueryReturn} - The result of the search within the fetched collection. */ - nearMedia(media: string | Buffer, type: NearMediaType, opts?: NearOptions): QueryReturn; + nearMedia, RV extends ReturnVectors>( + media: string | Buffer, + type: NearMediaType, + opts?: NearOptions + ): QueryReturn; } interface NearObject { @@ -407,7 +448,10 @@ interface NearObject { * @param {BaseNearOptions} [opts] - The available options for the search excluding the `groupBy` param. * @returns {Promise>} - The result of the search within the fetched collection. */ - nearObject(id: string, opts?: BaseNearOptions): Promise>; + nearObject, RV extends ReturnVectors>( + id: string, + opts?: BaseNearOptions + ): Promise>; /** * Search for objects in this collection by another object using a vector-based similarity search. * @@ -419,7 +463,10 @@ interface NearObject { * @param {GroupByNearOptions} opts - The available options for the search including the `groupBy` param. * @returns {Promise>} - The group by result of the search within the fetched collection. */ - nearObject(id: string, opts: GroupByNearOptions): Promise>; + nearObject, RV extends ReturnVectors>( + id: string, + opts: GroupByNearOptions + ): Promise>; /** * Search for objects in this collection by another object using a vector-based similarity search. * @@ -431,7 +478,10 @@ interface NearObject { * @param {NearOptions} [opts] - The available options for the search. * @returns {QueryReturn} - The result of the search within the fetched collection. */ - nearObject(id: string, opts?: NearOptions): QueryReturn; + nearObject, RV extends ReturnVectors>( + id: string, + opts?: NearOptions + ): QueryReturn; } interface NearText { @@ -448,7 +498,10 @@ interface NearText { * @param {BaseNearTextOptions} [opts] - The available options for the search excluding the `groupBy` param. * @returns {Promise>} - The result of the search within the fetched collection. */ - nearText(query: string | string[], opts?: BaseNearTextOptions): Promise>; + nearText, RV extends ReturnVectors>( + query: string | string[], + opts?: BaseNearTextOptions + ): Promise>; /** * Search for objects in this collection by text using text-capable vectorization module and vector-based similarity search. * You must have a text-capable vectorization module installed in order to use this method, @@ -462,7 +515,10 @@ interface NearText { * @param {GroupByNearTextOptions} opts - The available options for the search including the `groupBy` param. * @returns {Promise>} - The group by result of the search within the fetched collection. */ - nearText(query: string | string[], opts: GroupByNearTextOptions): Promise>; + nearText, RV extends ReturnVectors>( + query: string | string[], + opts: GroupByNearTextOptions + ): Promise>; /** * Search for objects in this collection by text using text-capable vectorization module and vector-based similarity search. * You must have a text-capable vectorization module installed in order to use this method, @@ -476,7 +532,10 @@ interface NearText { * @param {NearTextOptions} [opts] - The available options for the search. * @returns {QueryReturn} - The result of the search within the fetched collection. */ - nearText(query: string | string[], opts?: NearTextOptions): QueryReturn; + nearText, RV extends ReturnVectors>( + query: string | string[], + opts?: NearTextOptions + ): QueryReturn; } interface NearVector { @@ -491,7 +550,10 @@ interface NearVector { * @param {BaseNearOptions} [opts] - The available options for the search excluding the `groupBy` param. * @returns {Promise>} - The result of the search within the fetched collection. */ - nearVector(vector: NearVectorInputType, opts?: BaseNearOptions): Promise>; + nearVector, RV extends ReturnVectors>( + vector: NearVectorInputType, + opts?: BaseNearOptions + ): Promise>; /** * Search for objects by vector in this collection using a vector-based similarity search. * @@ -503,7 +565,10 @@ interface NearVector { * @param {GroupByNearOptions} opts - The available options for the search including the `groupBy` param. * @returns {Promise>} - The group by result of the search within the fetched collection. */ - nearVector(vector: NearVectorInputType, opts: GroupByNearOptions): Promise>; + nearVector, RV extends ReturnVectors>( + vector: NearVectorInputType, + opts: GroupByNearOptions + ): Promise>; /** * Search for objects by vector in this collection using a vector-based similarity search. * @@ -515,7 +580,10 @@ interface NearVector { * @param {NearOptions} [opts] - The available options for the search. * @returns {QueryReturn} - The result of the search within the fetched collection. */ - nearVector(vector: NearVectorInputType, opts?: NearOptions): QueryReturn; + nearVector, RV extends ReturnVectors>( + vector: NearVectorInputType, + opts?: NearOptions + ): QueryReturn; } /** All the available methods on the `.query` namespace. */ @@ -534,7 +602,10 @@ export interface Query * @param {FetchObjectByIdOptions} [opts] - The available options for fetching the object. * @returns {Promise | null>} - The object with the given UUID, or null if it does not exist. */ - fetchObjectById: (id: string, opts?: FetchObjectByIdOptions) => Promise | null>; + fetchObjectById: >( + id: string, + opts?: FetchObjectByIdOptions + ) => Promise> | null>; /** * Retrieve objects from the server without searching. @@ -542,13 +613,18 @@ export interface Query * @param {FetchObjectsOptions} [opts] - The available options for fetching the objects. * @returns {Promise>} - The objects within the fetched collection. */ - fetchObjects: (opts?: FetchObjectsOptions) => Promise>; + fetchObjects: >( + opts?: FetchObjectsOptions + ) => Promise>>; } /** Options available in the `query.nearImage`, `query.nearMedia`, `query.nearObject`, and `query.nearVector` methods */ -export type NearOptions = BaseNearOptions | GroupByNearOptions | undefined; +export type NearOptions = BaseNearOptions | GroupByNearOptions | undefined; /** Options available in the `query.nearText` method */ -export type NearTextOptions = BaseNearTextOptions | GroupByNearTextOptions | undefined; +export type NearTextOptions = + | BaseNearTextOptions + | GroupByNearTextOptions + | undefined; /** The return type of the `query` methods. It is a union of a standard query and a group by query due to function overloading. */ export type QueryReturn = Promise> | Promise>; diff --git a/src/collections/serialize/index.ts b/src/collections/serialize/index.ts index ec56f0c9..e4efd225 100644 --- a/src/collections/serialize/index.ts +++ b/src/collections/serialize/index.ts @@ -556,10 +556,7 @@ class Search { }; }; - private static metadata = ( - includeVector?: boolean | string[], - metadata?: QueryMetadata - ): MetadataRequest => { + private static metadata = (includeVector?: I, metadata?: QueryMetadata): MetadataRequest => { const out: any = { uuid: true, vector: typeof includeVector === 'boolean' ? includeVector : false, @@ -620,7 +617,7 @@ class Search { return args.groupBy !== undefined; }; - private static common = (args?: SearchOptions): BaseSearchArgs => { + private static common = (args?: SearchOptions): BaseSearchArgs => { const out: BaseSearchArgs = { autocut: args?.autoLimit, limit: args?.limit, @@ -666,7 +663,7 @@ class Search { }); }; - public static hybrid = async ( + public static hybrid = async ( args: { query: string; supportsTargets: boolean; @@ -674,113 +671,115 @@ class Search { supportsWeightsForTargets: boolean; supportsVectors: boolean; }, - opts?: HybridOptions + opts?: HybridOptions ): Promise => { return { - ...Search.common(opts), + ...Search.common(opts), hybridSearch: await Serialize.hybridSearch({ ...args, ...opts }), - groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, + groupBy: Search.isGroupBy>(opts) + ? Search.groupBy(opts.groupBy) + : undefined, }; }; - public static nearAudio = ( + public static nearAudio = ( args: { audio: string; supportsTargets: boolean; supportsWeightsForTargets: boolean; }, - opts?: NearOptions + opts?: NearOptions ): SearchNearAudioArgs => { return { ...Search.common(opts), nearAudio: Serialize.nearAudioSearch({ ...args, ...opts }), - groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, + groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, }; }; - public static nearDepth = ( + public static nearDepth = ( args: { depth: string; supportsTargets: boolean; supportsWeightsForTargets: boolean; }, - opts?: NearOptions + opts?: NearOptions ): SearchNearDepthArgs => { return { ...Search.common(opts), nearDepth: Serialize.nearDepthSearch({ ...args, ...opts }), - groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, + groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, }; }; - public static nearImage = ( + public static nearImage = ( args: { image: string; supportsTargets: boolean; supportsWeightsForTargets: boolean; }, - opts?: NearOptions + opts?: NearOptions ): SearchNearImageArgs => { return { ...Search.common(opts), nearImage: Serialize.nearImageSearch({ ...args, ...opts }), - groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, + groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, }; }; - public static nearIMU = ( + public static nearIMU = ( args: { imu: string; supportsTargets: boolean; supportsWeightsForTargets: boolean; }, - opts?: NearOptions + opts?: NearOptions ): SearchNearIMUArgs => { return { ...Search.common(opts), nearIMU: Serialize.nearIMUSearch({ ...args, ...opts }), - groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, + groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, }; }; - public static nearObject = ( + public static nearObject = ( args: { id: string; supportsTargets: boolean; supportsWeightsForTargets: boolean }, - opts?: NearOptions + opts?: NearOptions ): SearchNearObjectArgs => { return { ...Search.common(opts), nearObject: Serialize.nearObjectSearch({ ...args, ...opts }), - groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, + groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, }; }; - public static nearText = ( + public static nearText = ( args: { query: string | string[]; supportsTargets: boolean; supportsWeightsForTargets: boolean; }, - opts?: NearTextOptions + opts?: NearTextOptions ): SearchNearTextArgs => { return { ...Search.common(opts), nearText: Serialize.nearTextSearch({ ...args, ...opts }), - groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, + groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, }; }; - public static nearThermal = ( + public static nearThermal = ( args: { thermal: string; supportsTargets: boolean; supportsWeightsForTargets: boolean }, - opts?: NearOptions + opts?: NearOptions ): SearchNearThermalArgs => { return { ...Search.common(opts), nearThermal: Serialize.nearThermalSearch({ ...args, ...opts }), - groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, + groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, }; }; - public static nearVector = async ( + public static nearVector = async ( args: { vector: NearVectorInputType; supportsTargets: boolean; @@ -788,22 +787,22 @@ class Search { supportsWeightsForTargets: boolean; supportsVectors: boolean; }, - opts?: NearOptions + opts?: NearOptions ): Promise => { return { ...Search.common(opts), nearVector: await Serialize.nearVectorSearch({ ...args, ...opts }), - groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, + groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, }; }; - public static nearVideo = ( + public static nearVideo = ( args: { video: string; supportsTargets: boolean; supportsWeightsForTargets: boolean }, - opts?: NearOptions + opts?: NearOptions ): SearchNearVideoArgs => { return { ...Search.common(opts), nearVideo: Serialize.nearVideoSearch({ ...args, ...opts }), - groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, + groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, }; }; } @@ -812,15 +811,15 @@ export class Serialize { static aggregate = Aggregate; static search = Search; - public static isNamedVectors = (opts?: BaseNearOptions): boolean => { + public static isNamedVectors = (opts?: BaseNearOptions): boolean => { return Array.isArray(opts?.includeVector) || opts?.targetVector !== undefined; }; - public static isMultiTarget = (opts?: BaseNearOptions): boolean => { + public static isMultiTarget = (opts?: BaseNearOptions): boolean => { return opts?.targetVector !== undefined && !TargetVectorInputGuards.isSingle(opts.targetVector); }; - public static isMultiWeightPerTarget = (opts?: BaseNearOptions): boolean => { + public static isMultiWeightPerTarget = (opts?: BaseNearOptions): boolean => { return ( opts?.targetVector !== undefined && TargetVectorInputGuards.isMultiJoin(opts.targetVector) && @@ -980,8 +979,8 @@ export class Serialize { }); }; - public static isHybridVectorSearch = ( - vector: BaseHybridOptions['vector'] + public static isHybridVectorSearch = ( + vector: BaseHybridOptions['vector'] ): vector is | PrimitiveVectorType | Record< @@ -995,24 +994,24 @@ export class Serialize { ); }; - public static isHybridNearTextSearch = ( - vector: BaseHybridOptions['vector'] + public static isHybridNearTextSearch = ( + vector: BaseHybridOptions['vector'] ): vector is HybridNearTextSubSearch => { return (vector as HybridNearTextSubSearch)?.query !== undefined; }; - public static isHybridNearVectorSearch = ( - vector: BaseHybridOptions['vector'] + public static isHybridNearVectorSearch = ( + vector: BaseHybridOptions['vector'] ): vector is HybridNearVectorSubSearch => { return (vector as HybridNearVectorSubSearch)?.vector !== undefined; }; - private static hybridVector = async (args: { + private static hybridVector = async (args: { supportsTargets: boolean; supportsVectorsForTargets: boolean; supportsWeightsForTargets: boolean; supportsVectors: boolean; - vector?: BaseHybridOptions['vector']; + vector?: BaseHybridOptions['vector']; }) => { const vector = args.vector; if (Serialize.isHybridVectorSearch(vector)) { @@ -1110,8 +1109,12 @@ export class Serialize { }); }; - public static nearAudioSearch = ( - args: { audio: string; supportsTargets: boolean; supportsWeightsForTargets: boolean } & NearOptions + public static nearAudioSearch = ( + args: { audio: string; supportsTargets: boolean; supportsWeightsForTargets: boolean } & NearOptions< + T, + V, + I + > ): NearAudioSearch => { const { targets, targetVectors } = Serialize.targetVector(args); return NearAudioSearch.fromPartial({ @@ -1123,8 +1126,12 @@ export class Serialize { }); }; - public static nearDepthSearch = ( - args: { depth: string; supportsTargets: boolean; supportsWeightsForTargets: boolean } & NearOptions + public static nearDepthSearch = ( + args: { depth: string; supportsTargets: boolean; supportsWeightsForTargets: boolean } & NearOptions< + T, + V, + I + > ): NearDepthSearch => { const { targets, targetVectors } = Serialize.targetVector(args); return NearDepthSearch.fromPartial({ @@ -1136,8 +1143,12 @@ export class Serialize { }); }; - public static nearImageSearch = ( - args: { image: string; supportsTargets: boolean; supportsWeightsForTargets: boolean } & NearOptions + public static nearImageSearch = ( + args: { image: string; supportsTargets: boolean; supportsWeightsForTargets: boolean } & NearOptions< + T, + V, + I + > ): NearImageSearch => { const { targets, targetVectors } = Serialize.targetVector(args); return NearImageSearch.fromPartial({ @@ -1149,8 +1160,8 @@ export class Serialize { }); }; - public static nearIMUSearch = ( - args: { imu: string; supportsTargets: boolean; supportsWeightsForTargets: boolean } & NearOptions + public static nearIMUSearch = ( + args: { imu: string; supportsTargets: boolean; supportsWeightsForTargets: boolean } & NearOptions ): NearIMUSearch => { const { targets, targetVectors } = Serialize.targetVector(args); return NearIMUSearch.fromPartial({ @@ -1162,8 +1173,8 @@ export class Serialize { }); }; - public static nearObjectSearch = ( - args: { id: string; supportsTargets: boolean; supportsWeightsForTargets: boolean } & NearOptions + public static nearObjectSearch = ( + args: { id: string; supportsTargets: boolean; supportsWeightsForTargets: boolean } & NearOptions ): NearObject => { const { targets, targetVectors } = Serialize.targetVector(args); return NearObject.fromPartial({ @@ -1209,10 +1220,11 @@ export class Serialize { }); }; - public static nearThermalSearch = ( + public static nearThermalSearch = ( args: { thermal: string; supportsTargets: boolean; supportsWeightsForTargets: boolean } & NearOptions< T, - V + V, + I > ): NearThermalSearch => { const { targets, targetVectors } = Serialize.targetVector(args); @@ -1558,8 +1570,12 @@ export class Serialize { } }; - public static nearVideoSearch = ( - args: { video: string; supportsTargets: boolean; supportsWeightsForTargets: boolean } & NearOptions + public static nearVideoSearch = ( + args: { video: string; supportsTargets: boolean; supportsWeightsForTargets: boolean } & NearOptions< + T, + V, + I + > ): NearVideoSearch => { const { targets, targetVectors } = Serialize.targetVector(args); return NearVideoSearch.fromPartial({ diff --git a/src/collections/types/query.ts b/src/collections/types/query.ts index 52def317..8587baa3 100644 --- a/src/collections/types/query.ts +++ b/src/collections/types/query.ts @@ -61,7 +61,9 @@ export interface Vectors { [k: string]: PrimitiveVectorType; } -export type ReturnVectors = I extends true +export type ReturnVectors = V extends undefined + ? undefined + : I extends true ? V : I extends Array ? Pick< diff --git a/src/collections/vectors/journey.test.ts b/src/collections/vectors/journey.test.ts index 2b0cd08f..de2ab644 100644 --- a/src/collections/vectors/journey.test.ts +++ b/src/collections/vectors/journey.test.ts @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/no-non-null-assertion */ +/* eslint-disable @typescript-eslint/no-non-null-asserted-optional-chain */ import weaviate, { VectorIndexConfigHNSW, WeaviateClient, @@ -81,7 +83,7 @@ only('Testing of the collection.query methods with a collection with multvectors }); }); - it('should be able to get the inserted object with its vectors', async () => { + it('should be able to get the inserted object with its vectors stated implicitly', async () => { const obj = await collection.query.fetchObjectById(id1, { includeVector: true }); const assert = (obj: any): obj is WeaviateGenericObject, MyVectors> => { expect(obj).not.toBeNull(); @@ -100,6 +102,34 @@ only('Testing of the collection.query methods with a collection with multvectors } }); + it('should be able to get the inserted object with its vectors stated explicitly', async () => { + const obj = await collection.query.fetchObjectById(id1, { includeVector: ['regular', 'colbert'] }); + const assert = (obj: any): obj is WeaviateGenericObject, MyVectors> => { + expect(obj).not.toBeNull(); + return true; + }; + if (assert(obj)) { + singleVector = obj.vectors.regular; + multiVector = obj.vectors.colbert; + expect(obj.uuid).toBe(id1); + expect(obj.vectors).toBeDefined(); + expect(obj.vectors.regular).toEqual([1, 2, 3, 4]); + expect(obj.vectors.colbert).toEqual([ + [1, 2], + [3, 4], + ]); + } + }); + + it('should be able to get the inserted object with one of its vectors', async () => { + const obj = await collection.query.fetchObjectById(id1, { includeVector: ['regular'] }); + singleVector = obj?.vectors.regular!; + expect(obj?.uuid).toBe(id1); + expect(obj?.vectors).toBeDefined(); + expect(obj?.vectors.regular).toEqual([1, 2, 3, 4]); + expect((obj?.vectors as MyVectors).colbert).toBeUndefined(); + }); + it('should be able to query with hybrid for the inserted object over the single vector space', async () => { const result = await collection.query.hybrid('', { alpha: 1,