From ee87235ff5e5c062e028966d30226fea95e0f456 Mon Sep 17 00:00:00 2001 From: harpreet-applify Date: Tue, 9 May 2023 12:57:11 +0530 Subject: [PATCH] Vector search #131 --- CHANGELOG.md | 4 +++ README.md | 2 +- example/console-simple/bin/search.dart | 36 ++++++++++++++++++++++++++ example/console-simple/pubspec.lock | 2 +- lib/src/models/field.dart | 15 +++++++++++ pubspec.yaml | 2 +- 6 files changed, 58 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a31420f..ddd4f05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 0.3.1 + +* Added `dimensions` field to support creating a vector field in schema. + # 0.3.0+1 * Update README. diff --git a/README.md b/README.md index 6c87268..e2e469b 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Add `typesense` as a [dependency in your pubspec.yaml file](https://flutter.dev/ ```@yaml dependencies: - typesense: ^0.3.0 + typesense: ^0.3.1 ``` ## Usage diff --git a/example/console-simple/bin/search.dart b/example/console-simple/bin/search.dart index 0a20d10..5b1fc79 100644 --- a/example/console-simple/bin/search.dart +++ b/example/console-simple/bin/search.dart @@ -12,6 +12,7 @@ Future runExample(Client client) async { await init(client); await search(client); await geosearch(client); + await vectorsearch(client); await multisearch(client); await collections.delete(client); } @@ -139,6 +140,41 @@ Future geosearch(Client client) async { } } +Future vectorsearch(Client client) async { + try { + await collections.create( + client, + Schema( + 'docs', + { + Field('title', type: Type.string), + Field('points', type: Type.int32), + Field('vec', type: Type.float, isMultivalued: true, dimensions: 4), + }, + defaultSortingField: Field('points', type: Type.int32), + )); + await documents.importDocs(client, 'docs', [ + { + 'title': 'Louvre Museuem', + 'points': 1, + 'vec': [0.04, 0.234, 0.113, 0.001] + } + ]); + + logInfoln(log, 'Vector search.'); + log.fine(await client.collection('docs').documents.search({ + 'q': '*', + 'vector_query': 'vec:([0.96826, 0.94, 0.39557, 0.306488], k:100)', + })); + + await collections.delete(client, 'docs'); + } on RequestException catch (e, stackTrace) { + log.severe(e.message, e, stackTrace); + } catch (e, stackTrace) { + log.severe(e, stackTrace); + } +} + Future multisearch(Client client) async { try { logInfoln(log, 'Executing multiple searches.'); diff --git a/example/console-simple/pubspec.lock b/example/console-simple/pubspec.lock index 6c26de0..ff90a31 100644 --- a/example/console-simple/pubspec.lock +++ b/example/console-simple/pubspec.lock @@ -112,6 +112,6 @@ packages: path: "../.." relative: true source: path - version: "0.3.0+1" + version: "0.3.1" sdks: dart: ">=2.17.0 <3.0.0" diff --git a/lib/src/models/field.dart b/lib/src/models/field.dart index d4981ff..2a841de 100644 --- a/lib/src/models/field.dart +++ b/lib/src/models/field.dart @@ -14,6 +14,10 @@ class Field { /// [Type.float], [Type.bool] or [Type.geopoint] final bool isMultivalued; + /// Used in case of a vector field. Represents the number of dimensions + /// (length of the float array) that your embeddings contain. + final int dimensions; + /// If this field can be ommited in a document. final bool isOptional; @@ -43,6 +47,7 @@ class Field { this.name, { this.type, this.isMultivalued = false, + this.dimensions = 0, this.isOptional = false, this.isFacetable = false, this.shouldIndex = true, @@ -65,6 +70,7 @@ class Field { ? _Type.fromValue(map['type'], isMultivalued) : null, isMultivalued: isMultivalued, + dimensions: map['num_dim'] ?? 0, isOptional: map['optional'] ?? false, isFacetable: map['facet'] ?? false, shouldIndex: map['index'] ?? true, @@ -80,6 +86,9 @@ class Field { if (type != null) { map['type'] = type!.value(isMultivalued); } + if (dimensions > 0) { + map['num_dim'] = dimensions; + } if (isOptional) { map['optional'] = true; } @@ -111,6 +120,7 @@ class Field { name.hashCode ^ type.hashCode ^ isMultivalued.hashCode ^ + dimensions.hashCode ^ isOptional.hashCode ^ isFacetable.hashCode ^ shouldIndex.hashCode ^ @@ -125,6 +135,7 @@ class Field { other.name == name && other.type == type && other.isMultivalued == isMultivalued && + other.dimensions == dimensions && other.isOptional == isOptional && other.isFacetable == isFacetable && other.shouldIndex == shouldIndex && @@ -147,6 +158,7 @@ class UpdateField extends Field { super.name, { super.type, super.isMultivalued, + super.dimensions, super.isOptional, super.isFacetable, super.shouldIndex, @@ -172,6 +184,7 @@ class UpdateField extends Field { field.name, type: field.type, isMultivalued: field.isMultivalued, + dimensions: field.dimensions, isOptional: field.isOptional, isFacetable: field.isFacetable, shouldIndex: field.shouldIndex, @@ -187,6 +200,7 @@ class UpdateField extends Field { name.hashCode ^ type.hashCode ^ isMultivalued.hashCode ^ + dimensions.hashCode ^ isOptional.hashCode ^ isFacetable.hashCode ^ shouldIndex.hashCode ^ @@ -202,6 +216,7 @@ class UpdateField extends Field { other.name == name && other.type == type && other.isMultivalued == isMultivalued && + other.dimensions == dimensions && other.isOptional == isOptional && other.isFacetable == isFacetable && other.shouldIndex == shouldIndex && diff --git a/pubspec.yaml b/pubspec.yaml index 9038bcf..101435d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: typesense description: Dart client library for accessing the HTTP API of Typesense search engine. -version: 0.3.0+1 +version: 0.3.1 homepage: https://typesense.org/ repository: https://github.com/typesense/typesense-dart