@mastra/couchbase 0.0.3-alpha.0 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +28 -0
- package/dist/index.cjs +80 -71
- package/dist/index.js +80 -71
- package/package.json +3 -3
- package/src/vector/index.integration.test.ts +62 -1
- package/src/vector/index.ts +78 -67
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
|
|
2
|
-
> @mastra/couchbase@0.0.3-alpha.
|
|
2
|
+
> @mastra/couchbase@0.0.3-alpha.1 build /home/runner/work/mastra/mastra/stores/couchbase
|
|
3
3
|
> tsup src/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
6
6
|
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
7
7
|
[34mCLI[39m tsup v8.4.0
|
|
8
8
|
[34mTSC[39m Build start
|
|
9
|
-
[32mTSC[39m ⚡️ Build success in
|
|
9
|
+
[32mTSC[39m ⚡️ Build success in 6514ms
|
|
10
10
|
[34mDTS[39m Build start
|
|
11
11
|
[34mCLI[39m Target: es2022
|
|
12
12
|
Analysis will use the bundled TypeScript version 5.8.3
|
|
13
13
|
[36mWriting package typings: /home/runner/work/mastra/mastra/stores/couchbase/dist/_tsup-dts-rollup.d.ts[39m
|
|
14
14
|
Analysis will use the bundled TypeScript version 5.8.3
|
|
15
15
|
[36mWriting package typings: /home/runner/work/mastra/mastra/stores/couchbase/dist/_tsup-dts-rollup.d.cts[39m
|
|
16
|
-
[32mDTS[39m ⚡️ Build success in
|
|
16
|
+
[32mDTS[39m ⚡️ Build success in 9687ms
|
|
17
17
|
[34mCLI[39m Cleaning output folder
|
|
18
18
|
[34mESM[39m Build start
|
|
19
19
|
[34mCJS[39m Build start
|
|
20
|
-
[32mESM[39m [1mdist/index.js [22m[32m8.
|
|
21
|
-
[32mESM[39m ⚡️ Build success in
|
|
22
|
-
[32mCJS[39m [1mdist/index.cjs [22m[32m8.
|
|
23
|
-
[32mCJS[39m ⚡️ Build success in
|
|
20
|
+
[32mESM[39m [1mdist/index.js [22m[32m8.52 KB[39m
|
|
21
|
+
[32mESM[39m ⚡️ Build success in 620ms
|
|
22
|
+
[32mCJS[39m [1mdist/index.cjs [22m[32m8.58 KB[39m
|
|
23
|
+
[32mCJS[39m ⚡️ Build success in 624ms
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# @mastra/couchbase
|
|
2
2
|
|
|
3
|
+
## 0.0.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 9cd1a46: [MASTRA-3338] update naming scheme for embedding index based on vector store rules and added duplicate index checks
|
|
8
|
+
- Updated dependencies [e450778]
|
|
9
|
+
- Updated dependencies [8902157]
|
|
10
|
+
- Updated dependencies [ca0dc88]
|
|
11
|
+
- Updated dependencies [526c570]
|
|
12
|
+
- Updated dependencies [d7a6a33]
|
|
13
|
+
- Updated dependencies [9cd1a46]
|
|
14
|
+
- Updated dependencies [b5d2de0]
|
|
15
|
+
- Updated dependencies [644f8ad]
|
|
16
|
+
- Updated dependencies [70dbf51]
|
|
17
|
+
- @mastra/core@0.9.3
|
|
18
|
+
|
|
19
|
+
## 0.0.3-alpha.1
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- 9cd1a46: [MASTRA-3338] update naming scheme for embedding index based on vector store rules and added duplicate index checks
|
|
24
|
+
- Updated dependencies [e450778]
|
|
25
|
+
- Updated dependencies [8902157]
|
|
26
|
+
- Updated dependencies [ca0dc88]
|
|
27
|
+
- Updated dependencies [9cd1a46]
|
|
28
|
+
- Updated dependencies [70dbf51]
|
|
29
|
+
- @mastra/core@0.9.3-alpha.1
|
|
30
|
+
|
|
3
31
|
## 0.0.3-alpha.0
|
|
4
32
|
|
|
5
33
|
### Patch Changes
|
package/dist/index.cjs
CHANGED
|
@@ -59,86 +59,95 @@ var CouchbaseVector = class extends vector.MastraVector {
|
|
|
59
59
|
if (!Number.isInteger(dimension) || dimension <= 0) {
|
|
60
60
|
throw new Error("Dimension must be a positive integer");
|
|
61
61
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
mapping: {
|
|
74
|
-
default_analyzer: "standard",
|
|
75
|
-
default_datetime_parser: "dateTimeOptional",
|
|
76
|
-
default_field: "_all",
|
|
77
|
-
default_mapping: {
|
|
78
|
-
dynamic: true,
|
|
79
|
-
enabled: false
|
|
62
|
+
try {
|
|
63
|
+
await this.scope.searchIndexes().upsertIndex({
|
|
64
|
+
name: indexName,
|
|
65
|
+
sourceName: this.bucketName,
|
|
66
|
+
type: "fulltext-index",
|
|
67
|
+
params: {
|
|
68
|
+
doc_config: {
|
|
69
|
+
docid_prefix_delim: "",
|
|
70
|
+
docid_regexp: "",
|
|
71
|
+
mode: "scope.collection.type_field",
|
|
72
|
+
type_field: "type"
|
|
80
73
|
},
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
// [Doc](https://docs.couchbase.com/server/current/search/search-index-params.html#params) mentions this attribute is required for vector search to return the indexed field
|
|
87
|
-
type_field: "_type",
|
|
88
|
-
types: {
|
|
89
|
-
[`${this.scopeName}.${this.collectionName}`]: {
|
|
74
|
+
mapping: {
|
|
75
|
+
default_analyzer: "standard",
|
|
76
|
+
default_datetime_parser: "dateTimeOptional",
|
|
77
|
+
default_field: "_all",
|
|
78
|
+
default_mapping: {
|
|
90
79
|
dynamic: true,
|
|
91
|
-
enabled:
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
80
|
+
enabled: false
|
|
81
|
+
},
|
|
82
|
+
default_type: "_default",
|
|
83
|
+
docvalues_dynamic: true,
|
|
84
|
+
// [Doc](https://docs.couchbase.com/server/current/search/search-index-params.html#params) mentions this attribute is required for vector search to return the indexed field
|
|
85
|
+
index_dynamic: true,
|
|
86
|
+
store_dynamic: true,
|
|
87
|
+
// [Doc](https://docs.couchbase.com/server/current/search/search-index-params.html#params) mentions this attribute is required for vector search to return the indexed field
|
|
88
|
+
type_field: "_type",
|
|
89
|
+
types: {
|
|
90
|
+
[`${this.scopeName}.${this.collectionName}`]: {
|
|
91
|
+
dynamic: true,
|
|
92
|
+
enabled: true,
|
|
93
|
+
properties: {
|
|
94
|
+
embedding: {
|
|
95
|
+
enabled: true,
|
|
96
|
+
fields: [
|
|
97
|
+
{
|
|
98
|
+
dims: dimension,
|
|
99
|
+
index: true,
|
|
100
|
+
name: "embedding",
|
|
101
|
+
similarity: DISTANCE_MAPPING[metric],
|
|
102
|
+
type: "vector",
|
|
103
|
+
vector_index_optimized_for: "recall",
|
|
104
|
+
store: true,
|
|
105
|
+
// CHANGED due to https://docs.couchbase.com/server/current/search/search-index-params.html#fields
|
|
106
|
+
docvalues: true,
|
|
107
|
+
// CHANGED due to https://docs.couchbase.com/server/current/search/search-index-params.html#fields
|
|
108
|
+
include_term_vectors: true
|
|
109
|
+
// CHANGED due to https://docs.couchbase.com/server/current/search/search-index-params.html#fields
|
|
110
|
+
}
|
|
111
|
+
]
|
|
112
|
+
},
|
|
113
|
+
content: {
|
|
114
|
+
enabled: true,
|
|
115
|
+
fields: [
|
|
116
|
+
{
|
|
117
|
+
index: true,
|
|
118
|
+
name: "content",
|
|
119
|
+
store: true,
|
|
120
|
+
type: "text"
|
|
121
|
+
}
|
|
122
|
+
]
|
|
123
|
+
}
|
|
122
124
|
}
|
|
123
125
|
}
|
|
124
126
|
}
|
|
127
|
+
},
|
|
128
|
+
store: {
|
|
129
|
+
indexType: "scorch",
|
|
130
|
+
segmentVersion: 16
|
|
125
131
|
}
|
|
126
132
|
},
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
133
|
+
sourceUuid: "",
|
|
134
|
+
sourceParams: {},
|
|
135
|
+
sourceType: "gocbcore",
|
|
136
|
+
planParams: {
|
|
137
|
+
maxPartitionsPerPIndex: 64,
|
|
138
|
+
indexPartitions: 16,
|
|
139
|
+
numReplicas: 0
|
|
130
140
|
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
numReplicas: 0
|
|
141
|
+
});
|
|
142
|
+
this.vector_dimension = dimension;
|
|
143
|
+
} catch (error) {
|
|
144
|
+
const message = error?.message || error?.toString();
|
|
145
|
+
if (message && message.toLowerCase().includes("index exists")) {
|
|
146
|
+
await this.validateExistingIndex(indexName, dimension, metric);
|
|
147
|
+
return;
|
|
139
148
|
}
|
|
140
|
-
|
|
141
|
-
|
|
149
|
+
throw error;
|
|
150
|
+
}
|
|
142
151
|
}
|
|
143
152
|
async upsert(params) {
|
|
144
153
|
const { vectors, metadata, ids } = params;
|
package/dist/index.js
CHANGED
|
@@ -57,86 +57,95 @@ var CouchbaseVector = class extends MastraVector {
|
|
|
57
57
|
if (!Number.isInteger(dimension) || dimension <= 0) {
|
|
58
58
|
throw new Error("Dimension must be a positive integer");
|
|
59
59
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
mapping: {
|
|
72
|
-
default_analyzer: "standard",
|
|
73
|
-
default_datetime_parser: "dateTimeOptional",
|
|
74
|
-
default_field: "_all",
|
|
75
|
-
default_mapping: {
|
|
76
|
-
dynamic: true,
|
|
77
|
-
enabled: false
|
|
60
|
+
try {
|
|
61
|
+
await this.scope.searchIndexes().upsertIndex({
|
|
62
|
+
name: indexName,
|
|
63
|
+
sourceName: this.bucketName,
|
|
64
|
+
type: "fulltext-index",
|
|
65
|
+
params: {
|
|
66
|
+
doc_config: {
|
|
67
|
+
docid_prefix_delim: "",
|
|
68
|
+
docid_regexp: "",
|
|
69
|
+
mode: "scope.collection.type_field",
|
|
70
|
+
type_field: "type"
|
|
78
71
|
},
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
// [Doc](https://docs.couchbase.com/server/current/search/search-index-params.html#params) mentions this attribute is required for vector search to return the indexed field
|
|
85
|
-
type_field: "_type",
|
|
86
|
-
types: {
|
|
87
|
-
[`${this.scopeName}.${this.collectionName}`]: {
|
|
72
|
+
mapping: {
|
|
73
|
+
default_analyzer: "standard",
|
|
74
|
+
default_datetime_parser: "dateTimeOptional",
|
|
75
|
+
default_field: "_all",
|
|
76
|
+
default_mapping: {
|
|
88
77
|
dynamic: true,
|
|
89
|
-
enabled:
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
78
|
+
enabled: false
|
|
79
|
+
},
|
|
80
|
+
default_type: "_default",
|
|
81
|
+
docvalues_dynamic: true,
|
|
82
|
+
// [Doc](https://docs.couchbase.com/server/current/search/search-index-params.html#params) mentions this attribute is required for vector search to return the indexed field
|
|
83
|
+
index_dynamic: true,
|
|
84
|
+
store_dynamic: true,
|
|
85
|
+
// [Doc](https://docs.couchbase.com/server/current/search/search-index-params.html#params) mentions this attribute is required for vector search to return the indexed field
|
|
86
|
+
type_field: "_type",
|
|
87
|
+
types: {
|
|
88
|
+
[`${this.scopeName}.${this.collectionName}`]: {
|
|
89
|
+
dynamic: true,
|
|
90
|
+
enabled: true,
|
|
91
|
+
properties: {
|
|
92
|
+
embedding: {
|
|
93
|
+
enabled: true,
|
|
94
|
+
fields: [
|
|
95
|
+
{
|
|
96
|
+
dims: dimension,
|
|
97
|
+
index: true,
|
|
98
|
+
name: "embedding",
|
|
99
|
+
similarity: DISTANCE_MAPPING[metric],
|
|
100
|
+
type: "vector",
|
|
101
|
+
vector_index_optimized_for: "recall",
|
|
102
|
+
store: true,
|
|
103
|
+
// CHANGED due to https://docs.couchbase.com/server/current/search/search-index-params.html#fields
|
|
104
|
+
docvalues: true,
|
|
105
|
+
// CHANGED due to https://docs.couchbase.com/server/current/search/search-index-params.html#fields
|
|
106
|
+
include_term_vectors: true
|
|
107
|
+
// CHANGED due to https://docs.couchbase.com/server/current/search/search-index-params.html#fields
|
|
108
|
+
}
|
|
109
|
+
]
|
|
110
|
+
},
|
|
111
|
+
content: {
|
|
112
|
+
enabled: true,
|
|
113
|
+
fields: [
|
|
114
|
+
{
|
|
115
|
+
index: true,
|
|
116
|
+
name: "content",
|
|
117
|
+
store: true,
|
|
118
|
+
type: "text"
|
|
119
|
+
}
|
|
120
|
+
]
|
|
121
|
+
}
|
|
120
122
|
}
|
|
121
123
|
}
|
|
122
124
|
}
|
|
125
|
+
},
|
|
126
|
+
store: {
|
|
127
|
+
indexType: "scorch",
|
|
128
|
+
segmentVersion: 16
|
|
123
129
|
}
|
|
124
130
|
},
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
131
|
+
sourceUuid: "",
|
|
132
|
+
sourceParams: {},
|
|
133
|
+
sourceType: "gocbcore",
|
|
134
|
+
planParams: {
|
|
135
|
+
maxPartitionsPerPIndex: 64,
|
|
136
|
+
indexPartitions: 16,
|
|
137
|
+
numReplicas: 0
|
|
128
138
|
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
numReplicas: 0
|
|
139
|
+
});
|
|
140
|
+
this.vector_dimension = dimension;
|
|
141
|
+
} catch (error) {
|
|
142
|
+
const message = error?.message || error?.toString();
|
|
143
|
+
if (message && message.toLowerCase().includes("index exists")) {
|
|
144
|
+
await this.validateExistingIndex(indexName, dimension, metric);
|
|
145
|
+
return;
|
|
137
146
|
}
|
|
138
|
-
|
|
139
|
-
|
|
147
|
+
throw error;
|
|
148
|
+
}
|
|
140
149
|
}
|
|
141
150
|
async upsert(params) {
|
|
142
151
|
const { vectors, metadata, ids } = params;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastra/couchbase",
|
|
3
|
-
"version": "0.0.3
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "Couchbase vector store provider for Mastra",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"couchbase": "^4.4.5",
|
|
23
|
-
"@mastra/core": "^0.9.3
|
|
23
|
+
"@mastra/core": "^0.9.3"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@microsoft/api-extractor": "^7.52.1",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"tsup": "^8.4.0",
|
|
33
33
|
"typescript": "^5.8.2",
|
|
34
34
|
"vitest": "^3.0.9",
|
|
35
|
-
"@internal/lint": "0.0.
|
|
35
|
+
"@internal/lint": "0.0.4"
|
|
36
36
|
},
|
|
37
37
|
"scripts": {
|
|
38
38
|
"build": "tsup src/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting",
|
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
// The tests will automatically start and configure the required Couchbase container.
|
|
4
4
|
|
|
5
5
|
import { execSync } from 'child_process';
|
|
6
|
+
import { randomUUID } from 'crypto';
|
|
6
7
|
import axios from 'axios';
|
|
7
8
|
import type { Cluster, Bucket, Scope, Collection } from 'couchbase';
|
|
8
9
|
import { connect } from 'couchbase';
|
|
9
|
-
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
|
10
|
+
import { describe, it, expect, beforeAll, afterAll, vi } from 'vitest';
|
|
10
11
|
import { CouchbaseVector, DISTANCE_MAPPING } from './index';
|
|
11
12
|
|
|
12
13
|
const containerName = 'mastra_couchbase_testing';
|
|
@@ -431,6 +432,66 @@ describe('Integration Testing CouchbaseVector', async () => {
|
|
|
431
432
|
}),
|
|
432
433
|
).rejects.toThrow('No vectors provided');
|
|
433
434
|
}, 50000);
|
|
435
|
+
|
|
436
|
+
it('should handle non-existent index queries', async () => {
|
|
437
|
+
await expect(
|
|
438
|
+
couchbase_client.query({ indexName: 'non-existent-index', queryVector: [1, 2, 3] }),
|
|
439
|
+
).rejects.toThrow();
|
|
440
|
+
}, 50000);
|
|
441
|
+
|
|
442
|
+
it('should handle duplicate index creation gracefully', async () => {
|
|
443
|
+
const duplicateIndexName = `duplicate-test-${randomUUID()}`;
|
|
444
|
+
const dimension = 768;
|
|
445
|
+
const infoSpy = vi.spyOn(couchbase_client['logger'], 'info');
|
|
446
|
+
const warnSpy = vi.spyOn(couchbase_client['logger'], 'warn');
|
|
447
|
+
|
|
448
|
+
try {
|
|
449
|
+
// Create index first time
|
|
450
|
+
await couchbase_client.createIndex({
|
|
451
|
+
indexName: duplicateIndexName,
|
|
452
|
+
dimension,
|
|
453
|
+
metric: 'cosine',
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
// Try to create with same dimensions - should not throw
|
|
457
|
+
await expect(
|
|
458
|
+
couchbase_client.createIndex({
|
|
459
|
+
indexName: duplicateIndexName,
|
|
460
|
+
dimension,
|
|
461
|
+
metric: 'cosine',
|
|
462
|
+
}),
|
|
463
|
+
).resolves.not.toThrow();
|
|
464
|
+
|
|
465
|
+
expect(infoSpy).toHaveBeenCalledWith(expect.stringContaining('already exists with'));
|
|
466
|
+
|
|
467
|
+
// Try to create with same dimensions and different metric - should not throw
|
|
468
|
+
await expect(
|
|
469
|
+
couchbase_client.createIndex({
|
|
470
|
+
indexName: duplicateIndexName,
|
|
471
|
+
dimension,
|
|
472
|
+
metric: 'euclidean',
|
|
473
|
+
}),
|
|
474
|
+
).resolves.not.toThrow();
|
|
475
|
+
|
|
476
|
+
expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('Attempted to create index with metric'));
|
|
477
|
+
|
|
478
|
+
// Try to create with different dimensions - should throw
|
|
479
|
+
await expect(
|
|
480
|
+
couchbase_client.createIndex({
|
|
481
|
+
indexName: duplicateIndexName,
|
|
482
|
+
dimension: dimension + 1,
|
|
483
|
+
metric: 'cosine',
|
|
484
|
+
}),
|
|
485
|
+
).rejects.toThrow(
|
|
486
|
+
`Index "${duplicateIndexName}" already exists with ${dimension} dimensions, but ${dimension + 1} dimensions were requested`,
|
|
487
|
+
);
|
|
488
|
+
} finally {
|
|
489
|
+
infoSpy.mockRestore();
|
|
490
|
+
warnSpy.mockRestore();
|
|
491
|
+
// Cleanup
|
|
492
|
+
await couchbase_client.deleteIndex(duplicateIndexName);
|
|
493
|
+
}
|
|
494
|
+
}, 50000);
|
|
434
495
|
});
|
|
435
496
|
|
|
436
497
|
describe('Vector Dimension Tracking', () => {
|
package/src/vector/index.ts
CHANGED
|
@@ -84,81 +84,92 @@ export class CouchbaseVector extends MastraVector {
|
|
|
84
84
|
throw new Error('Dimension must be a positive integer');
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
mapping: {
|
|
99
|
-
default_analyzer: 'standard',
|
|
100
|
-
default_datetime_parser: 'dateTimeOptional',
|
|
101
|
-
default_field: '_all',
|
|
102
|
-
default_mapping: {
|
|
103
|
-
dynamic: true,
|
|
104
|
-
enabled: false,
|
|
87
|
+
try {
|
|
88
|
+
await this.scope.searchIndexes().upsertIndex({
|
|
89
|
+
name: indexName,
|
|
90
|
+
sourceName: this.bucketName,
|
|
91
|
+
type: 'fulltext-index',
|
|
92
|
+
params: {
|
|
93
|
+
doc_config: {
|
|
94
|
+
docid_prefix_delim: '',
|
|
95
|
+
docid_regexp: '',
|
|
96
|
+
mode: 'scope.collection.type_field',
|
|
97
|
+
type_field: 'type',
|
|
105
98
|
},
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
types: {
|
|
112
|
-
[`${this.scopeName}.${this.collectionName}`]: {
|
|
99
|
+
mapping: {
|
|
100
|
+
default_analyzer: 'standard',
|
|
101
|
+
default_datetime_parser: 'dateTimeOptional',
|
|
102
|
+
default_field: '_all',
|
|
103
|
+
default_mapping: {
|
|
113
104
|
dynamic: true,
|
|
114
|
-
enabled:
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
105
|
+
enabled: false,
|
|
106
|
+
},
|
|
107
|
+
default_type: '_default',
|
|
108
|
+
docvalues_dynamic: true, // [Doc](https://docs.couchbase.com/server/current/search/search-index-params.html#params) mentions this attribute is required for vector search to return the indexed field
|
|
109
|
+
index_dynamic: true,
|
|
110
|
+
store_dynamic: true, // [Doc](https://docs.couchbase.com/server/current/search/search-index-params.html#params) mentions this attribute is required for vector search to return the indexed field
|
|
111
|
+
type_field: '_type',
|
|
112
|
+
types: {
|
|
113
|
+
[`${this.scopeName}.${this.collectionName}`]: {
|
|
114
|
+
dynamic: true,
|
|
115
|
+
enabled: true,
|
|
116
|
+
properties: {
|
|
117
|
+
embedding: {
|
|
118
|
+
enabled: true,
|
|
119
|
+
fields: [
|
|
120
|
+
{
|
|
121
|
+
dims: dimension,
|
|
122
|
+
index: true,
|
|
123
|
+
name: 'embedding',
|
|
124
|
+
similarity: DISTANCE_MAPPING[metric],
|
|
125
|
+
type: 'vector',
|
|
126
|
+
vector_index_optimized_for: 'recall',
|
|
127
|
+
store: true, // CHANGED due to https://docs.couchbase.com/server/current/search/search-index-params.html#fields
|
|
128
|
+
docvalues: true, // CHANGED due to https://docs.couchbase.com/server/current/search/search-index-params.html#fields
|
|
129
|
+
include_term_vectors: true, // CHANGED due to https://docs.couchbase.com/server/current/search/search-index-params.html#fields
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
},
|
|
133
|
+
content: {
|
|
134
|
+
enabled: true,
|
|
135
|
+
fields: [
|
|
136
|
+
{
|
|
137
|
+
index: true,
|
|
138
|
+
name: 'content',
|
|
139
|
+
store: true,
|
|
140
|
+
type: 'text',
|
|
141
|
+
},
|
|
142
|
+
],
|
|
143
|
+
},
|
|
142
144
|
},
|
|
143
145
|
},
|
|
144
146
|
},
|
|
145
147
|
},
|
|
148
|
+
store: {
|
|
149
|
+
indexType: 'scorch',
|
|
150
|
+
segmentVersion: 16,
|
|
151
|
+
},
|
|
146
152
|
},
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
153
|
+
sourceUuid: '',
|
|
154
|
+
sourceParams: {},
|
|
155
|
+
sourceType: 'gocbcore',
|
|
156
|
+
planParams: {
|
|
157
|
+
maxPartitionsPerPIndex: 64,
|
|
158
|
+
indexPartitions: 16,
|
|
159
|
+
numReplicas: 0,
|
|
150
160
|
},
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
161
|
+
});
|
|
162
|
+
this.vector_dimension = dimension;
|
|
163
|
+
} catch (error: any) {
|
|
164
|
+
// Check for 'already exists' error (Couchbase may throw a 400 or 409, or have a message)
|
|
165
|
+
const message = error?.message || error?.toString();
|
|
166
|
+
if (message && message.toLowerCase().includes('index exists')) {
|
|
167
|
+
// Fetch index info and check dimension
|
|
168
|
+
await this.validateExistingIndex(indexName, dimension, metric);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
throw error;
|
|
172
|
+
}
|
|
162
173
|
}
|
|
163
174
|
|
|
164
175
|
async upsert(params: UpsertVectorParams): Promise<string[]> {
|