UNPKG

weaviate-client

Version:
345 lines (344 loc) 9.31 kB
import { WeaviateInvalidInputError } from '../../errors.js'; import { FilterReferenceCount, FilterReferenceMultiTarget, FilterReferenceSingleTarget, FilterTarget, } from '../../proto/v1/base.js'; import { TargetGuards } from './utils.js'; /** * Use this class when you want to chain filters together using logical operators. * * Since JS/TS has no native support for & and | as logical operators, you must use these methods and nest * the filters you want to combine. * * ANDs and ORs can be nested an arbitrary number of times. * * @example * ```ts * const filter = Filters.and( * collection.filter.byProperty('name').equal('John'), * collection.filter.byProperty('age').greaterThan(18), * ); * ``` */ export class Filters { /** * Combine filters using the logical AND operator. * * @param {FilterValue[]} filters The filters to combine. */ static and(...filters) { return { operator: 'And', filters: filters, value: null, }; } /** * Combine filters using the logical OR operator. * * @param {FilterValue[]} filters The filters to combine. */ static or(...filters) { return { operator: 'Or', filters: filters, value: null, }; } } export class FilterBase { constructor(property, target) { this.property = property; this.target = target; } targetPath() { if (!this.target) { return FilterTarget.fromPartial({ property: TargetGuards.isProperty(this.property) ? this.property : undefined, count: TargetGuards.isCountRef(this.property) ? FilterReferenceCount.fromPartial({ on: this.property.linkOn, }) : undefined, }); } let target = this.target; while (target.target !== undefined) { if (TargetGuards.isTargetRef(target.target)) { target = target.target; } else { throw new WeaviateInvalidInputError('Invalid target reference'); } } target.target = this.property; return this.resolveTargets(this.target); } resolveTargets(internal) { return FilterTarget.fromPartial({ property: TargetGuards.isProperty(internal) ? internal : undefined, singleTarget: TargetGuards.isSingleTargetRef(internal) ? FilterReferenceSingleTarget.fromPartial({ on: internal.linkOn, target: this.resolveTargets(internal.target), }) : undefined, multiTarget: TargetGuards.isMultiTargetRef(internal) ? FilterReferenceMultiTarget.fromPartial({ on: internal.linkOn, targetCollection: internal.targetCollection, target: this.resolveTargets(internal.target), }) : undefined, count: TargetGuards.isCountRef(internal) ? FilterReferenceCount.fromPartial({ on: internal.linkOn, }) : undefined, }); } } export class FilterProperty extends FilterBase { constructor(property, length, target) { super(length ? `len(${property})` : property, target); } isNull(value) { return { operator: 'IsNull', target: this.targetPath(), value: value, }; } containsAny(value) { return { operator: 'ContainsAny', target: this.targetPath(), value: value, }; } containsAll(value) { return { operator: 'ContainsAll', target: this.targetPath(), value: value, }; } equal(value) { return { operator: 'Equal', target: this.targetPath(), value: value, }; } notEqual(value) { return { operator: 'NotEqual', target: this.targetPath(), value: value, }; } lessThan(value) { return { operator: 'LessThan', target: this.targetPath(), value: value, }; } lessOrEqual(value) { return { operator: 'LessThanEqual', target: this.targetPath(), value: value, }; } greaterThan(value) { return { operator: 'GreaterThan', target: this.targetPath(), value: value, }; } greaterOrEqual(value) { return { operator: 'GreaterThanEqual', target: this.targetPath(), value: value, }; } like(value) { return { operator: 'Like', target: this.targetPath(), value: value, }; } withinGeoRange(value) { return { operator: 'WithinGeoRange', target: this.targetPath(), value: value, }; } } export class FilterRef { constructor(target) { this.target = target; } byRef(linkOn) { this.target.target = { type_: 'single', linkOn: linkOn }; return new FilterRef(this.target); } byRefMultiTarget(linkOn, targetCollection) { this.target.target = { type_: 'multi', linkOn: linkOn, targetCollection: targetCollection }; return new FilterRef(this.target); } byProperty(name, length = false) { return new FilterProperty(name, length, this.target); } byRefCount(linkOn) { return new FilterCount(linkOn, this.target); } byId() { return new FilterId(this.target); } byCreationTime() { return new FilterCreationTime(this.target); } byUpdateTime() { return new FilterUpdateTime(this.target); } } export class FilterCount extends FilterBase { constructor(linkOn, target) { super({ type_: 'count', linkOn }, target); } equal(value) { return { operator: 'Equal', target: this.targetPath(), value: value, }; } notEqual(value) { return { operator: 'NotEqual', target: this.targetPath(), value: value, }; } lessThan(value) { return { operator: 'LessThan', target: this.targetPath(), value: value, }; } lessOrEqual(value) { return { operator: 'LessThanEqual', target: this.targetPath(), value: value, }; } greaterThan(value) { return { operator: 'GreaterThan', target: this.targetPath(), value: value, }; } greaterOrEqual(value) { return { operator: 'GreaterThanEqual', target: this.targetPath(), value: value, }; } } export class FilterId extends FilterBase { constructor(target) { super('_id', target); } equal(value) { return { operator: 'Equal', target: this.targetPath(), value: value, }; } notEqual(value) { return { operator: 'NotEqual', target: this.targetPath(), value: value, }; } containsAny(value) { return { operator: 'ContainsAny', target: this.targetPath(), value: value, }; } } export class FilterTime extends FilterBase { containsAny(value) { return { operator: 'ContainsAny', target: this.targetPath(), value: value.map(this.toValue), }; } equal(value) { return { operator: 'Equal', target: this.targetPath(), value: this.toValue(value), }; } notEqual(value) { return { operator: 'NotEqual', target: this.targetPath(), value: this.toValue(value), }; } lessThan(value) { return { operator: 'LessThan', target: this.targetPath(), value: this.toValue(value), }; } lessOrEqual(value) { return { operator: 'LessThanEqual', target: this.targetPath(), value: this.toValue(value), }; } greaterThan(value) { return { operator: 'GreaterThan', target: this.targetPath(), value: this.toValue(value), }; } greaterOrEqual(value) { return { operator: 'GreaterThanEqual', target: this.targetPath(), value: this.toValue(value), }; } toValue(value) { return value instanceof Date ? value.toISOString() : value; } } export class FilterCreationTime extends FilterTime { constructor(target) { super('_creationTimeUnix', target); } } export class FilterUpdateTime extends FilterTime { constructor(target) { super('_lastUpdateTimeUnix', target); } }