@travetto/model-mongo 7.0.0-rc.3 → 7.0.0-rc.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/model-mongo",
3
- "version": "7.0.0-rc.3",
3
+ "version": "7.0.0-rc.4",
4
4
  "description": "Mongo backing for the travetto model module.",
5
5
  "keywords": [
6
6
  "mongo",
@@ -25,10 +25,10 @@
25
25
  "directory": "module/model-mongo"
26
26
  },
27
27
  "dependencies": {
28
- "@travetto/cli": "^7.0.0-rc.3",
29
- "@travetto/config": "^7.0.0-rc.3",
30
- "@travetto/model": "^7.0.0-rc.3",
31
- "@travetto/model-query": "^7.0.0-rc.3",
28
+ "@travetto/cli": "^7.0.0-rc.4",
29
+ "@travetto/config": "^7.0.0-rc.4",
30
+ "@travetto/model": "^7.0.0-rc.4",
31
+ "@travetto/model-query": "^7.0.0-rc.4",
32
32
  "mongodb": "^7.0.0"
33
33
  },
34
34
  "travetto": {
@@ -32,6 +32,10 @@ export type PlainIdx = Record<string, -1 | 0 | 1>;
32
32
  */
33
33
  export class MongoUtil {
34
34
 
35
+ static namespaceIndex(cls: Class, name: string): string {
36
+ return `${cls.Ⲑid}__${name}`.replace(/[^a-zA-Z0-9_]+/g, '_');
37
+ }
38
+
35
39
  static toIndex<T extends ModelType>(field: IndexField<T>): PlainIdx {
36
40
  const keys = [];
37
41
  while (typeof field !== 'number' && typeof field !== 'boolean' && Object.keys(field)) {
@@ -150,24 +154,21 @@ export class MongoUtil {
150
154
  return out;
151
155
  }
152
156
 
153
- static getExtraIndices<T extends ModelType>(cls: Class<T>): BasicIdx[] {
154
- const out: BasicIdx[] = [];
157
+ static getExtraIndices<T extends ModelType>(cls: Class<T>): [BasicIdx, IdxConfig][] {
158
+ const out: [BasicIdx, IdxConfig][] = [];
155
159
  const textFields: string[] = [];
156
160
  SchemaRegistryIndex.visitFields(cls, (field, path) => {
157
161
  if (field.type === PointConcrete) {
158
162
  const name = [...path, field].map(schema => schema.name).join('.');
159
- out.push({ [name]: '2d' });
163
+ out.push([{ [name]: '2d' }, { name: this.namespaceIndex(cls, name) }]);
160
164
  } else if (field.specifiers?.includes('text') && (field.specifiers?.includes('long') || field.specifiers.includes('search'))) {
161
165
  const name = [...path, field].map(schema => schema.name).join('.');
162
166
  textFields.push(name);
163
167
  }
164
168
  });
165
169
  if (textFields.length) {
166
- const text: BasicIdx = {};
167
- for (const field of textFields) {
168
- text[field] = 'text';
169
- }
170
- out.push(text);
170
+ const text: BasicIdx = Object.fromEntries(textFields.map(field => [field, 'text']));
171
+ out.push([text, { name: this.namespaceIndex(cls, 'text_search') }]);
171
172
  }
172
173
  return out;
173
174
  }
@@ -182,8 +183,8 @@ export class MongoUtil {
182
183
 
183
184
  static getIndices<T extends ModelType>(cls: Class<T>, indices: IndexConfig<ModelType>[] = []): [BasicIdx, IdxConfig][] {
184
185
  return [
185
- ...indices.map(idx => [this.getPlainIndex(idx), (idx.type === 'unique' ? { unique: true } : {})] as const),
186
- ...this.getExtraIndices(cls).map((idx) => [idx, {}] as const)
186
+ ...indices.map(idx => [this.getPlainIndex(idx), { ...(idx.type === 'unique' ? { unique: true } : {}), name: this.namespaceIndex(cls, idx.name) }] as const),
187
+ ...this.getExtraIndices(cls)
187
188
  ].map(idx => [...idx]);
188
189
  }
189
190
 
@@ -215,31 +216,30 @@ export class MongoUtil {
215
216
  }
216
217
 
217
218
  static isIndexChanged(existing: IndexDescriptionInfo, [pendingKey, pendingOptions]: [BasicIdx, CreateIndexesOptions]): boolean {
219
+ let changed = false;
218
220
  // Config changed
219
- if (
221
+ changed ||=
220
222
  !!existing.unique !== !!pendingOptions.unique ||
221
223
  !!existing.sparse !== !!pendingOptions.sparse ||
222
224
  existing.expireAfterSeconds !== pendingOptions.expireAfterSeconds ||
223
- existing.bucketSize !== pendingOptions.bucketSize
224
- ) {
225
- return true;
226
- }
225
+ existing.bucketSize !== pendingOptions.bucketSize;
226
+
227
+ const existingFields = existing.textIndexVersion ?
228
+ Object.fromEntries(Object.entries(existing.weights ?? {}).map(([key]) => [key, 'text'])) :
229
+ existing.key;
230
+
227
231
  const pendingKeySet = new Set(Object.keys(pendingKey));
228
- const existingKeySet = new Set(Object.keys(existing.key));
232
+ const existingKeySet = new Set(Object.keys(existingFields));
229
233
 
230
- if (pendingKeySet.size !== existingKeySet.size) {
231
- return true;
232
- }
234
+ changed ||= pendingKeySet.size !== existingKeySet.size;
233
235
 
234
- const overlap = pendingKeySet.intersection(existingKeySet);
235
- if (overlap.size !== pendingKeySet.size) {
236
- return true;
237
- }
238
- for (const key of overlap) {
239
- if (existing.key[key] !== pendingKey[key]) {
240
- return false;
241
- }
236
+ const overlap = [...pendingKeySet.intersection(existingKeySet)];
237
+ changed ||= overlap.length !== pendingKeySet.size;
238
+
239
+ for (let i = 0; i < overlap.length && !changed; i++) {
240
+ changed ||= existingFields[overlap[i]] !== pendingKey[overlap[i]];
242
241
  }
243
- return false;
242
+
243
+ return changed;
244
244
  }
245
245
  }