weaviate-client
Version:
JS/TS client for Weaviate
461 lines (460 loc) • 26.1 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MetricsManager = exports.metrics = void 0;
const errors_js_1 = require("../../errors.js");
const index_js_1 = require("../../graphql/index.js");
const index_js_2 = require("../../index.js");
const index_js_3 = require("../deserialize/index.js");
const utils_js_1 = require("../query/utils.js");
const index_js_4 = require("../serialize/index.js");
const metrics = () => {
return {
aggregate: (property) => new MetricsManager(property),
};
};
exports.metrics = metrics;
class MetricsManager {
constructor(property) {
this.propertyName = property;
}
map(metrics) {
const out = {};
metrics.forEach((metric) => {
out[metric] = true;
});
return out;
}
/**
* Define the metrics to be returned for a BOOL or BOOL_ARRAY property when aggregating over a collection.
*
* If none of the arguments are provided then all metrics will be returned.
*
* @param {('count' | 'percentageFalse' | 'percentageTrue' | 'totalFalse' | 'totalTrue')[]} metrics The metrics to return.
* @returns {MetricsBoolean<P>} The metrics for the property.
*/
boolean(metrics) {
if (metrics === undefined || metrics.length === 0) {
metrics = ['count', 'percentageFalse', 'percentageTrue', 'totalFalse', 'totalTrue'];
}
return Object.assign(Object.assign({}, this.map(metrics)), { kind: 'boolean', propertyName: this.propertyName });
}
/**
* Define the metrics to be returned for a DATE or DATE_ARRAY property when aggregating over a collection.
*
* If none of the arguments are provided then all metrics will be returned.
*
* @param {('count' | 'maximum' | 'median' | 'minimum' | 'mode')[]} metrics The metrics to return.
* @returns {MetricsDate<P>} The metrics for the property.
*/
date(metrics) {
if (metrics === undefined || metrics.length === 0) {
metrics = ['count', 'maximum', 'median', 'minimum', 'mode'];
}
return Object.assign(Object.assign({}, this.map(metrics)), { kind: 'date', propertyName: this.propertyName });
}
/**
* Define the metrics to be returned for an INT or INT_ARRAY property when aggregating over a collection.
*
* If none of the arguments are provided then all metrics will be returned.
*
* @param {('count' | 'maximum' | 'mean' | 'median' | 'minimum' | 'mode' | 'sum')[]} metrics The metrics to return.
* @returns {MetricsInteger<P>} The metrics for the property.
*/
integer(metrics) {
if (metrics === undefined || metrics.length === 0) {
metrics = ['count', 'maximum', 'mean', 'median', 'minimum', 'mode', 'sum'];
}
return Object.assign(Object.assign({}, this.map(metrics)), { kind: 'integer', propertyName: this.propertyName });
}
/**
* Define the metrics to be returned for a NUMBER or NUMBER_ARRAY property when aggregating over a collection.
*
* If none of the arguments are provided then all metrics will be returned.
*
* @param {('count' | 'maximum' | 'mean' | 'median' | 'minimum' | 'mode' | 'sum')[]} metrics The metrics to return.
* @returns {MetricsNumber<P>} The metrics for the property.
*/
number(metrics) {
if (metrics === undefined || metrics.length === 0) {
metrics = ['count', 'maximum', 'mean', 'median', 'minimum', 'mode', 'sum'];
}
return Object.assign(Object.assign({}, this.map(metrics)), { kind: 'number', propertyName: this.propertyName });
}
// public reference(metrics: 'pointingTo'[]): MetricsReference<T> {
// return {
// ...this.map(metrics),
// kind: 'reference',
// propertyName: this.propertyName,
// };
// }
/**
* Define the metrics to be returned for a TEXT or TEXT_ARRAY property when aggregating over a collection.
*
* If none of the arguments are provided then all metrics will be returned.
*
* @param {('count' | 'topOccurrencesOccurs' | 'topOccurrencesValue')[]} metrics The metrics to return.
* @param {number} [minOccurrences] The how many top occurrences to return.
* @returns {MetricsText<P>} The metrics for the property.
*/
text(metrics, minOccurrences) {
if (metrics === undefined || metrics.length === 0) {
metrics = ['count', 'topOccurrencesOccurs', 'topOccurrencesValue'];
}
return {
count: metrics.includes('count'),
topOccurrences: metrics.includes('topOccurrencesOccurs') || metrics.includes('topOccurrencesValue')
? {
occurs: metrics.includes('topOccurrencesOccurs'),
value: metrics.includes('topOccurrencesValue'),
}
: undefined,
minOccurrences,
kind: 'text',
propertyName: this.propertyName,
};
}
}
exports.MetricsManager = MetricsManager;
class AggregateManager {
constructor(connection, name, dbVersionSupport, consistencyLevel, tenant) {
this.grpc = () => this.connection.aggregate(this.name, this.consistencyLevel, this.tenant);
this.do = (query) => {
return query
.do()
.then(({ data }) => {
const _a = data.Aggregate[this.name][0], { meta } = _a, rest = __rest(_a, ["meta"]);
return {
properties: rest,
totalCount: meta === null || meta === void 0 ? void 0 : meta.count,
};
})
.catch((err) => {
throw new errors_js_1.WeaviateQueryError(err.message, 'GraphQL');
});
};
this.doGroupBy = (query) => {
return query
.do()
.then(({ data }) => data.Aggregate[this.name].map((item) => {
const { groupedBy, meta } = item, rest = __rest(item, ["groupedBy", "meta"]);
return {
groupedBy: {
prop: groupedBy.path[0],
value: groupedBy.value,
},
properties: rest,
totalCount: meta === null || meta === void 0 ? void 0 : meta.count,
};
}))
.catch((err) => {
throw new errors_js_1.WeaviateQueryError(err.message, 'GraphQL');
});
};
this.connection = connection;
this.name = name;
this.dbVersionSupport = dbVersionSupport;
this.consistencyLevel = consistencyLevel;
this.tenant = tenant;
this.grpcChecker = this.dbVersionSupport.supportsAggregateGRPC().then((res) => res.supports);
this.groupBy = {
hybrid: (query, opts) => __awaiter(this, void 0, void 0, function* () {
if (yield this.grpcChecker) {
const group = typeof opts.groupBy === 'string' ? { property: opts.groupBy } : opts.groupBy;
return this.grpc()
.then((aggregate) => __awaiter(this, void 0, void 0, function* () {
return aggregate.withHybrid(Object.assign(Object.assign({}, (yield index_js_4.Serialize.aggregate.hybrid(query, opts))), { groupBy: index_js_4.Serialize.aggregate.groupBy(group), limit: group.limit }));
}))
.then((reply) => index_js_3.Deserialize.aggregateGroupBy(reply));
}
let builder = this.base(opts === null || opts === void 0 ? void 0 : opts.returnMetrics, opts === null || opts === void 0 ? void 0 : opts.filters, opts === null || opts === void 0 ? void 0 : opts.groupBy).withHybrid({
query: query,
alpha: opts === null || opts === void 0 ? void 0 : opts.alpha,
maxVectorDistance: opts === null || opts === void 0 ? void 0 : opts.maxVectorDistance,
properties: opts === null || opts === void 0 ? void 0 : opts.queryProperties,
targetVectors: (opts === null || opts === void 0 ? void 0 : opts.targetVector) ? [opts.targetVector] : undefined,
vector: opts === null || opts === void 0 ? void 0 : opts.vector,
});
if (opts === null || opts === void 0 ? void 0 : opts.objectLimit) {
builder = builder.withObjectLimit(opts.objectLimit);
}
return this.doGroupBy(builder);
}),
nearImage: (image, opts) => __awaiter(this, void 0, void 0, function* () {
const [b64, usesGrpc] = yield Promise.all([yield (0, index_js_2.toBase64FromMedia)(image), yield this.grpcChecker]);
if (usesGrpc) {
const group = typeof opts.groupBy === 'string' ? { property: opts.groupBy } : opts.groupBy;
return this.grpc()
.then((aggregate) => aggregate.withNearImage(Object.assign(Object.assign({}, index_js_4.Serialize.aggregate.nearImage(b64, opts)), { groupBy: index_js_4.Serialize.aggregate.groupBy(group), limit: group.limit })))
.then((reply) => index_js_3.Deserialize.aggregateGroupBy(reply));
}
const builder = this.base(opts === null || opts === void 0 ? void 0 : opts.returnMetrics, opts === null || opts === void 0 ? void 0 : opts.filters, opts === null || opts === void 0 ? void 0 : opts.groupBy).withNearImage({
image: b64,
certainty: opts === null || opts === void 0 ? void 0 : opts.certainty,
distance: opts === null || opts === void 0 ? void 0 : opts.distance,
targetVectors: (opts === null || opts === void 0 ? void 0 : opts.targetVector) ? [opts.targetVector] : undefined,
});
if (opts === null || opts === void 0 ? void 0 : opts.objectLimit) {
builder.withObjectLimit(opts === null || opts === void 0 ? void 0 : opts.objectLimit);
}
return this.doGroupBy(builder);
}),
nearObject: (id, opts) => __awaiter(this, void 0, void 0, function* () {
if (yield this.grpcChecker) {
const group = typeof opts.groupBy === 'string' ? { property: opts.groupBy } : opts.groupBy;
return this.grpc()
.then((aggregate) => aggregate.withNearObject(Object.assign(Object.assign({}, index_js_4.Serialize.aggregate.nearObject(id, opts)), { groupBy: index_js_4.Serialize.aggregate.groupBy(group), limit: group.limit })))
.then((reply) => index_js_3.Deserialize.aggregateGroupBy(reply));
}
const builder = this.base(opts === null || opts === void 0 ? void 0 : opts.returnMetrics, opts === null || opts === void 0 ? void 0 : opts.filters, opts === null || opts === void 0 ? void 0 : opts.groupBy).withNearObject({
id: id,
certainty: opts === null || opts === void 0 ? void 0 : opts.certainty,
distance: opts === null || opts === void 0 ? void 0 : opts.distance,
targetVectors: (opts === null || opts === void 0 ? void 0 : opts.targetVector) ? [opts.targetVector] : undefined,
});
if (opts === null || opts === void 0 ? void 0 : opts.objectLimit) {
builder.withObjectLimit(opts.objectLimit);
}
return this.doGroupBy(builder);
}),
nearText: (query, opts) => __awaiter(this, void 0, void 0, function* () {
if (yield this.grpcChecker) {
const group = typeof opts.groupBy === 'string' ? { property: opts.groupBy } : opts.groupBy;
return this.grpc()
.then((aggregate) => aggregate.withNearText(Object.assign(Object.assign({}, index_js_4.Serialize.aggregate.nearText(query, opts)), { groupBy: index_js_4.Serialize.aggregate.groupBy(group), limit: group.limit })))
.then((reply) => index_js_3.Deserialize.aggregateGroupBy(reply));
}
const builder = this.base(opts === null || opts === void 0 ? void 0 : opts.returnMetrics, opts === null || opts === void 0 ? void 0 : opts.filters, opts === null || opts === void 0 ? void 0 : opts.groupBy).withNearText({
concepts: Array.isArray(query) ? query : [query],
certainty: opts === null || opts === void 0 ? void 0 : opts.certainty,
distance: opts === null || opts === void 0 ? void 0 : opts.distance,
targetVectors: (opts === null || opts === void 0 ? void 0 : opts.targetVector) ? [opts.targetVector] : undefined,
});
if (opts === null || opts === void 0 ? void 0 : opts.objectLimit) {
builder.withObjectLimit(opts.objectLimit);
}
return this.doGroupBy(builder);
}),
nearVector: (vector, opts) => __awaiter(this, void 0, void 0, function* () {
if (yield this.grpcChecker) {
const group = typeof opts.groupBy === 'string' ? { property: opts.groupBy } : opts.groupBy;
return this.grpc()
.then((aggregate) => __awaiter(this, void 0, void 0, function* () {
return aggregate.withNearVector(Object.assign(Object.assign({}, (yield index_js_4.Serialize.aggregate.nearVector(vector, opts))), { groupBy: index_js_4.Serialize.aggregate.groupBy(group), limit: group.limit }));
}))
.then((reply) => index_js_3.Deserialize.aggregateGroupBy(reply));
}
const builder = this.base(opts === null || opts === void 0 ? void 0 : opts.returnMetrics, opts === null || opts === void 0 ? void 0 : opts.filters, opts === null || opts === void 0 ? void 0 : opts.groupBy).withNearVector({
vector: vector,
certainty: opts === null || opts === void 0 ? void 0 : opts.certainty,
distance: opts === null || opts === void 0 ? void 0 : opts.distance,
targetVectors: (opts === null || opts === void 0 ? void 0 : opts.targetVector) ? [opts.targetVector] : undefined,
});
if (opts === null || opts === void 0 ? void 0 : opts.objectLimit) {
builder.withObjectLimit(opts.objectLimit);
}
return this.doGroupBy(builder);
}),
overAll: (opts) => __awaiter(this, void 0, void 0, function* () {
if (yield this.grpcChecker) {
const group = typeof opts.groupBy === 'string' ? { property: opts.groupBy } : opts.groupBy;
return this.grpc()
.then((aggregate) => aggregate.withFetch(Object.assign(Object.assign({}, index_js_4.Serialize.aggregate.overAll(opts)), { groupBy: index_js_4.Serialize.aggregate.groupBy(group), limit: group.limit })))
.then((reply) => index_js_3.Deserialize.aggregateGroupBy(reply));
}
const builder = this.base(opts === null || opts === void 0 ? void 0 : opts.returnMetrics, opts === null || opts === void 0 ? void 0 : opts.filters, opts === null || opts === void 0 ? void 0 : opts.groupBy);
return this.doGroupBy(builder);
}),
};
}
gql() {
return new index_js_1.Aggregator(this.connection);
}
base(metrics, filters, groupBy) {
let fields = 'meta { count }';
let builder = this.gql().withClassName(this.name);
if (metrics) {
if (Array.isArray(metrics)) {
fields += metrics.map((m) => this.metrics(m)).join(' ');
}
else {
fields += this.metrics(metrics);
}
}
if (groupBy) {
builder = builder.withGroupBy(typeof groupBy === 'string' ? [groupBy] : [groupBy.property]);
fields += 'groupedBy { path value }';
if (typeof groupBy !== 'string' && (groupBy === null || groupBy === void 0 ? void 0 : groupBy.limit)) {
builder = builder.withLimit(groupBy.limit);
}
}
if (fields !== '') {
builder = builder.withFields(fields);
}
if (filters) {
builder = builder.withWhere(index_js_4.Serialize.filtersREST(filters));
}
if (this.tenant) {
builder = builder.withTenant(this.tenant);
}
return builder;
}
metrics(metrics) {
let body = '';
const { kind, propertyName } = metrics, rest = __rest(metrics, ["kind", "propertyName"]);
switch (kind) {
case 'text': {
const _a = rest, { minOccurrences } = _a, restText = __rest(_a, ["minOccurrences"]);
body = Object.entries(restText)
.map(([key, value]) => {
if (value) {
return value instanceof Object
? `topOccurrences${minOccurrences ? `(limit: ${minOccurrences})` : ''} { ${value.occurs ? 'occurs' : ''} ${value.value ? 'value' : ''} }`
: key;
}
})
.join(' ');
break;
}
default:
body = Object.entries(rest)
.map(([key, value]) => (value ? key : ''))
.join(' ');
}
return `${propertyName} { ${body} }`;
}
static use(connection, name, dbVersionSupport, consistencyLevel, tenant) {
return new AggregateManager(connection, name, dbVersionSupport, consistencyLevel, tenant);
}
hybrid(query, opts) {
return __awaiter(this, void 0, void 0, function* () {
if (yield this.grpcChecker) {
return this.grpc()
.then((aggregate) => __awaiter(this, void 0, void 0, function* () { return aggregate.withHybrid(yield index_js_4.Serialize.aggregate.hybrid(query, opts)); }))
.then((reply) => index_js_3.Deserialize.aggregate(reply));
}
let builder = this.base(opts === null || opts === void 0 ? void 0 : opts.returnMetrics, opts === null || opts === void 0 ? void 0 : opts.filters).withHybrid({
query: query,
alpha: opts === null || opts === void 0 ? void 0 : opts.alpha,
maxVectorDistance: opts === null || opts === void 0 ? void 0 : opts.maxVectorDistance,
properties: opts === null || opts === void 0 ? void 0 : opts.queryProperties,
targetVectors: (opts === null || opts === void 0 ? void 0 : opts.targetVector) ? [opts.targetVector] : undefined,
vector: opts === null || opts === void 0 ? void 0 : opts.vector,
});
if (opts === null || opts === void 0 ? void 0 : opts.objectLimit) {
builder = builder.withObjectLimit(opts.objectLimit);
}
return this.do(builder);
});
}
nearImage(image, opts) {
return __awaiter(this, void 0, void 0, function* () {
const [b64, usesGrpc] = yield Promise.all([yield (0, index_js_2.toBase64FromMedia)(image), yield this.grpcChecker]);
if (usesGrpc) {
return this.grpc()
.then((aggregate) => aggregate.withNearImage(index_js_4.Serialize.aggregate.nearImage(b64, opts)))
.then((reply) => index_js_3.Deserialize.aggregate(reply));
}
const builder = this.base(opts === null || opts === void 0 ? void 0 : opts.returnMetrics, opts === null || opts === void 0 ? void 0 : opts.filters).withNearImage({
image: b64,
certainty: opts === null || opts === void 0 ? void 0 : opts.certainty,
distance: opts === null || opts === void 0 ? void 0 : opts.distance,
targetVectors: (opts === null || opts === void 0 ? void 0 : opts.targetVector) ? [opts.targetVector] : undefined,
});
if (opts === null || opts === void 0 ? void 0 : opts.objectLimit) {
builder.withObjectLimit(opts === null || opts === void 0 ? void 0 : opts.objectLimit);
}
return this.do(builder);
});
}
nearObject(id, opts) {
return __awaiter(this, void 0, void 0, function* () {
if (yield this.grpcChecker) {
return this.grpc()
.then((aggregate) => aggregate.withNearObject(index_js_4.Serialize.aggregate.nearObject(id, opts)))
.then((reply) => index_js_3.Deserialize.aggregate(reply));
}
const builder = this.base(opts === null || opts === void 0 ? void 0 : opts.returnMetrics, opts === null || opts === void 0 ? void 0 : opts.filters).withNearObject({
id: id,
certainty: opts === null || opts === void 0 ? void 0 : opts.certainty,
distance: opts === null || opts === void 0 ? void 0 : opts.distance,
targetVectors: (opts === null || opts === void 0 ? void 0 : opts.targetVector) ? [opts.targetVector] : undefined,
});
if (opts === null || opts === void 0 ? void 0 : opts.objectLimit) {
builder.withObjectLimit(opts.objectLimit);
}
return this.do(builder);
});
}
nearText(query, opts) {
return __awaiter(this, void 0, void 0, function* () {
if (yield this.grpcChecker) {
return this.grpc()
.then((aggregate) => aggregate.withNearText(index_js_4.Serialize.aggregate.nearText(query, opts)))
.then((reply) => index_js_3.Deserialize.aggregate(reply));
}
const builder = this.base(opts === null || opts === void 0 ? void 0 : opts.returnMetrics, opts === null || opts === void 0 ? void 0 : opts.filters).withNearText({
concepts: Array.isArray(query) ? query : [query],
certainty: opts === null || opts === void 0 ? void 0 : opts.certainty,
distance: opts === null || opts === void 0 ? void 0 : opts.distance,
targetVectors: (opts === null || opts === void 0 ? void 0 : opts.targetVector) ? [opts.targetVector] : undefined,
});
if (opts === null || opts === void 0 ? void 0 : opts.objectLimit) {
builder.withObjectLimit(opts.objectLimit);
}
return this.do(builder);
});
}
nearVector(vector, opts) {
return __awaiter(this, void 0, void 0, function* () {
if (yield this.grpcChecker) {
return this.grpc()
.then((aggregate) => __awaiter(this, void 0, void 0, function* () { return aggregate.withNearVector(yield index_js_4.Serialize.aggregate.nearVector(vector, opts)); }))
.then((reply) => index_js_3.Deserialize.aggregate(reply));
}
if (!utils_js_1.NearVectorInputGuards.is1D(vector)) {
throw new errors_js_1.WeaviateInvalidInputError('Vector can only be a 1D array of numbers when using `nearVector` with <1.29 Weaviate versions.');
}
const builder = this.base(opts === null || opts === void 0 ? void 0 : opts.returnMetrics, opts === null || opts === void 0 ? void 0 : opts.filters).withNearVector({
vector: vector,
certainty: opts === null || opts === void 0 ? void 0 : opts.certainty,
distance: opts === null || opts === void 0 ? void 0 : opts.distance,
targetVectors: (opts === null || opts === void 0 ? void 0 : opts.targetVector) ? [opts.targetVector] : undefined,
});
if (opts === null || opts === void 0 ? void 0 : opts.objectLimit) {
builder.withObjectLimit(opts.objectLimit);
}
return this.do(builder);
});
}
overAll(opts) {
return __awaiter(this, void 0, void 0, function* () {
if (yield this.grpcChecker) {
return this.grpc()
.then((aggregate) => aggregate.withFetch(index_js_4.Serialize.aggregate.overAll(opts)))
.then((reply) => index_js_3.Deserialize.aggregate(reply));
}
return this.do(this.base(opts === null || opts === void 0 ? void 0 : opts.returnMetrics, opts === null || opts === void 0 ? void 0 : opts.filters));
});
}
}
exports.default = AggregateManager.use;