Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ env:
WEAVIATE_124: 1.24.26
WEAVIATE_125: 1.25.28
WEAVIATE_126: 1.26.13
WEAVIATE_127: 1.27.8
WEAVIATE_128: 1.28.1-77a2178
WEAVIATE_127: 1.27.9
WEAVIATE_128: 1.28.2

jobs:
checks:
Expand Down
133 changes: 105 additions & 28 deletions src/collections/aggregate/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,25 @@ import { FilterValue } from '../filters/index.js';

import { WeaviateQueryError } from '../../errors.js';
import { Aggregator } from '../../graphql/index.js';
import { toBase64FromMedia } from '../../index.js';
import { PrimitiveKeys, toBase64FromMedia } from '../../index.js';
import { Bm25QueryProperty } from '../query/types.js';
import { Serialize } from '../serialize/index.js';

export type AggregateBaseOptions<T, M> = {
filters?: FilterValue;
returnMetrics?: M;
};

export type AggregateGroupByOptions<T, M> = AggregateOptions<T, M> & {
groupBy: (keyof T & string) | GroupByAggregate<T>;
export type AggregateGroupByOptions<T, M> = AggregateBaseOptions<T, M> & {
groupBy: T extends undefined ? string : (keyof T & string) | GroupByAggregate<T>;
};

export type GroupByAggregate<T> = {
property: keyof T & string;
property: T extends undefined ? string : keyof T & string;
limit?: number;
};

export type AggregateOptions<T, M> = AggregateBaseOptions<T, M>;

export type AggregateBaseOverAllOptions<T, M> = AggregateBaseOptions<T, M>;
export type AggregateOverAllOptions<T, M> = AggregateBaseOptions<T, M>;

export type AggregateNearOptions<T, M> = AggregateBaseOptions<T, M> & {
certainty?: number;
Expand All @@ -35,8 +34,21 @@ export type AggregateNearOptions<T, M> = AggregateBaseOptions<T, M> & {
targetVector?: string;
};

export type AggregateHybridOptions<T, M> = AggregateBaseOptions<T, M> & {
alpha?: number;
maxVectorDistance?: number;
objectLimit?: number;
queryProperties?: (PrimitiveKeys<T> | Bm25QueryProperty<T>)[];
targetVector?: string;
vector?: number[];
};

export type AggregateGroupByHybridOptions<T, M> = AggregateHybridOptions<T, M> & {
groupBy: T extends undefined ? string : (keyof T & string) | GroupByAggregate<T>;
};

export type AggregateGroupByNearOptions<T, M> = AggregateNearOptions<T, M> & {
groupBy: (keyof T & string) | GroupByAggregate<T>;
groupBy: T extends undefined ? string : (keyof T & string) | GroupByAggregate<T>;
};

export type AggregateBoolean = {
Expand Down Expand Up @@ -346,9 +358,26 @@ class AggregateManager<T> implements Aggregate<T> {
this.tenant = tenant;

this.groupBy = {
hybrid: <M extends PropertiesMetrics<T> | undefined = undefined>(
query: string,
opts: AggregateGroupByHybridOptions<T, M>
): Promise<AggregateGroupByResult<T, M>[]> => {
let builder = this.base(opts?.returnMetrics, opts?.filters, opts?.groupBy).withHybrid({
query: query,
alpha: opts?.alpha,
maxVectorDistance: opts?.maxVectorDistance,
properties: opts?.queryProperties as string[],
targetVectors: opts?.targetVector ? [opts.targetVector] : undefined,
vector: opts?.vector,
});
if (opts?.objectLimit) {
builder = builder.withObjectLimit(opts.objectLimit);
}
return this.doGroupBy(builder);
},
nearImage: async <M extends PropertiesMetrics<T> | undefined = undefined>(
image: string | Buffer,
opts?: AggregateGroupByNearOptions<T, M>
opts: AggregateGroupByNearOptions<T, M>
): Promise<AggregateGroupByResult<T, M>[]> => {
const builder = this.base(opts?.returnMetrics, opts?.filters, opts?.groupBy).withNearImage({
image: await toBase64FromMedia(image),
Expand All @@ -363,7 +392,7 @@ class AggregateManager<T> implements Aggregate<T> {
},
nearObject: <M extends PropertiesMetrics<T> | undefined = undefined>(
id: string,
opts?: AggregateGroupByNearOptions<T, M>
opts: AggregateGroupByNearOptions<T, M>
): Promise<AggregateGroupByResult<T, M>[]> => {
const builder = this.base(opts?.returnMetrics, opts?.filters, opts?.groupBy).withNearObject({
id: id,
Expand All @@ -378,7 +407,7 @@ class AggregateManager<T> implements Aggregate<T> {
},
nearText: <M extends PropertiesMetrics<T> | undefined = undefined>(
query: string | string[],
opts?: AggregateGroupByNearOptions<T, M>
opts: AggregateGroupByNearOptions<T, M>
): Promise<AggregateGroupByResult<T, M>[]> => {
const builder = this.base(opts?.returnMetrics, opts?.filters, opts?.groupBy).withNearText({
concepts: Array.isArray(query) ? query : [query],
Expand All @@ -393,7 +422,7 @@ class AggregateManager<T> implements Aggregate<T> {
},
nearVector: <M extends PropertiesMetrics<T> | undefined = undefined>(
vector: number[],
opts?: AggregateGroupByNearOptions<T, M>
opts: AggregateGroupByNearOptions<T, M>
): Promise<AggregateGroupByResult<T, M>[]> => {
const builder = this.base(opts?.returnMetrics, opts?.filters, opts?.groupBy).withNearVector({
vector: vector,
Expand Down Expand Up @@ -422,7 +451,7 @@ class AggregateManager<T> implements Aggregate<T> {
base(
metrics?: PropertiesMetrics<T>,
filters?: FilterValue,
groupBy?: (keyof T & string) | GroupByAggregate<T>
groupBy?: (keyof T & string) | GroupByAggregate<T> | string
) {
let fields = 'meta { count }';
let builder = this.query().withClassName(this.name);
Expand Down Expand Up @@ -489,6 +518,24 @@ class AggregateManager<T> implements Aggregate<T> {
return new AggregateManager<T>(connection, name, dbVersionSupport, consistencyLevel, tenant);
}

hybrid<M extends PropertiesMetrics<T>>(
query: string,
opts?: AggregateHybridOptions<T, M>
): Promise<AggregateResult<T, M>> {
let builder = this.base(opts?.returnMetrics, opts?.filters).withHybrid({
query: query,
alpha: opts?.alpha,
maxVectorDistance: opts?.maxVectorDistance,
properties: opts?.queryProperties as string[],
targetVectors: opts?.targetVector ? [opts.targetVector] : undefined,
vector: opts?.vector,
});
if (opts?.objectLimit) {
builder = builder.withObjectLimit(opts.objectLimit);
}
return this.do(builder);
}

async nearImage<M extends PropertiesMetrics<T>>(
image: string | Buffer,
opts?: AggregateNearOptions<T, M>
Expand Down Expand Up @@ -553,7 +600,9 @@ class AggregateManager<T> implements Aggregate<T> {
return this.do(builder);
}

overAll<M extends PropertiesMetrics<T>>(opts?: AggregateOptions<T, M>): Promise<AggregateResult<T, M>> {
overAll<M extends PropertiesMetrics<T>>(
opts?: AggregateOverAllOptions<T, M>
): Promise<AggregateResult<T, M>> {
const builder = this.base(opts?.returnMetrics, opts?.filters);
return this.do(builder);
}
Expand Down Expand Up @@ -588,7 +637,7 @@ class AggregateManager<T> implements Aggregate<T> {
prop: groupedBy.path[0],
value: groupedBy.value,
},
properties: rest.length > 0 ? rest : undefined,
properties: rest,
totalCount: meta?.count,
};
})
Expand All @@ -602,6 +651,19 @@ class AggregateManager<T> implements Aggregate<T> {
export interface Aggregate<T> {
/** This namespace contains methods perform a group by search while aggregating metrics. */
groupBy: AggregateGroupBy<T>;
/**
* Aggregate metrics over the objects returned by a hybrid search on this collection.
*
* This method requires that the objects in the collection have associated vectors.
*
* @param {string} query The text query to search for.
* @param {AggregateHybridOptions<T, M>} opts The options for the request.
* @returns {Promise<AggregateResult<T, M>[]>} The aggregated metrics for the objects returned by the vector search.
*/
hybrid<M extends PropertiesMetrics<T>>(
query: string,
opts?: AggregateHybridOptions<T, M>
): Promise<AggregateResult<T, M>>;
/**
* Aggregate metrics over the objects returned by a near image vector search on this collection.
*
Expand Down Expand Up @@ -668,72 +730,87 @@ export interface Aggregate<T> {
* @param {AggregateOptions<T, M>} [opts] The options for the request.
* @returns {Promise<AggregateResult<T, M>[]>} The aggregated metrics for the objects in the collection.
*/
overAll<M extends PropertiesMetrics<T>>(opts?: AggregateOptions<T, M>): Promise<AggregateResult<T, M>>;
overAll<M extends PropertiesMetrics<T>>(
opts?: AggregateOverAllOptions<T, M>
): Promise<AggregateResult<T, M>>;
}

export interface AggregateGroupBy<T> {
/**
* Aggregate metrics over the objects returned by a near image vector search on this collection.
* Aggregate metrics over the objects grouped by a specified property and returned by a hybrid search on this collection.
*
* This method requires that the objects in the collection have associated vectors.
*
* @param {string} query The text query to search for.
* @param {AggregateGroupByHybridOptions<T, M>} opts The options for the request.
* @returns {Promise<AggregateGroupByResult<T, M>[]>} The aggregated metrics for the objects returned by the vector search.
*/
hybrid<M extends PropertiesMetrics<T>>(
query: string,
opts: AggregateGroupByHybridOptions<T, M>
): Promise<AggregateGroupByResult<T, M>[]>;
/**
* Aggregate metrics over the objects grouped by a specified property and returned by a near image vector search on this collection.
*
* At least one of `certainty`, `distance`, or `object_limit` must be specified here for the vector search.
*
* This method requires a vectorizer capable of handling base64-encoded images, e.g. `img2vec-neural`, `multi2vec-clip`, and `multi2vec-bind`.
*
* @param {string | Buffer} image The image to search on. This can be a base64 string, a file path string, or a buffer.
* @param {AggregateGroupByNearOptions<T, M>} [opts] The options for the request.
* @param {AggregateGroupByNearOptions<T, M>} opts The options for the request.
* @returns {Promise<AggregateGroupByResult<T, M>[]>} The aggregated metrics for the objects returned by the vector search.
*/
nearImage<M extends PropertiesMetrics<T>>(
image: string | Buffer,
opts?: AggregateGroupByNearOptions<T, M>
opts: AggregateGroupByNearOptions<T, M>
): Promise<AggregateGroupByResult<T, M>[]>;
/**
* Aggregate metrics over the objects returned by a near object search on this collection.
* Aggregate metrics over the objects grouped by a specified property and returned by a near object search on this collection.
*
* At least one of `certainty`, `distance`, or `object_limit` must be specified here for the vector search.
*
* This method requires that the objects in the collection have associated vectors.
*
* @param {string} id The ID of the object to search for.
* @param {AggregateGroupByNearOptions<T, M>} [opts] The options for the request.
* @param {AggregateGroupByNearOptions<T, M>} opts The options for the request.
* @returns {Promise<AggregateGroupByResult<T, M>[]>} The aggregated metrics for the objects returned by the vector search.
*/
nearObject<M extends PropertiesMetrics<T>>(
id: string,
opts?: AggregateGroupByNearOptions<T, M>
opts: AggregateGroupByNearOptions<T, M>
): Promise<AggregateGroupByResult<T, M>[]>;
/**
* Aggregate metrics over the objects returned by a near text vector search on this collection.
* Aggregate metrics over the objects grouped by a specified property and returned by a near text vector search on this collection.
*
* At least one of `certainty`, `distance`, or `object_limit` must be specified here for the vector search.
*
* This method requires a vectorizer capable of handling text, e.g. `text2vec-contextionary`, `text2vec-openai`, etc.
*
* @param {string | string[]} query The text to search for.
* @param {AggregateGroupByNearOptions<T, M>} [opts] The options for the request.
* @param {AggregateGroupByNearOptions<T, M>} opts The options for the request.
* @returns {Promise<AggregateGroupByResult<T, M>[]>} The aggregated metrics for the objects returned by the vector search.
*/
nearText<M extends PropertiesMetrics<T>>(
query: string | string[],
opts: AggregateGroupByNearOptions<T, M>
): Promise<AggregateGroupByResult<T, M>[]>;
/**
* Aggregate metrics over the objects returned by a near vector search on this collection.
* Aggregate metrics over the objects grouped by a specified property and returned by a near vector search on this collection.
*
* At least one of `certainty`, `distance`, or `object_limit` must be specified here for the vector search.
*
* This method requires that the objects in the collection have associated vectors.
*
* @param {number[]} vector The vector to search for.
* @param {AggregateGroupByNearOptions<T, M>} [opts] The options for the request.
* @param {AggregateGroupByNearOptions<T, M>} opts The options for the request.
* @returns {Promise<AggregateGroupByResult<T, M>[]>} The aggregated metrics for the objects returned by the vector search.
*/
nearVector<M extends PropertiesMetrics<T>>(
vector: number[],
opts?: AggregateGroupByNearOptions<T, M>
opts: AggregateGroupByNearOptions<T, M>
): Promise<AggregateGroupByResult<T, M>[]>;
/**
* Aggregate metrics over all the objects in this collection without any vector search.
* Aggregate metrics over all the objects in this collection grouped by a specified property without any vector search.
*
* @param {AggregateGroupByOptions<T, M>} [opts] The options for the request.
* @returns {Promise<AggregateGroupByResult<T, M>[]>} The aggregated metrics for the objects in the collection.
Expand Down
Loading
Loading