@travetto/model-elasticsearch 6.0.0-rc.1 → 6.0.0-rc.2

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/README.md CHANGED
@@ -13,17 +13,17 @@ npm install @travetto/model-elasticsearch
13
13
  yarn add @travetto/model-elasticsearch
14
14
  ```
15
15
 
16
- This module provides an [elasticsearch](https://elastic.co)-based implementation of the [Data Modeling Support](https://github.com/travetto/travetto/tree/main/module/model#readme "Datastore abstraction for core operations."). This source allows the [Data Modeling Support](https://github.com/travetto/travetto/tree/main/module/model#readme "Datastore abstraction for core operations.") module to read, write and query against [elasticsearch](https://elastic.co). In development mode, [ElasticsearchModelService](https://github.com/travetto/travetto/tree/main/module/model-elasticsearch/src/service.ts#L37) will also modify the [elasticsearch](https://elastic.co) schema in real time to minimize impact to development.
16
+ This module provides an [elasticsearch](https://elastic.co)-based implementation of the [Data Modeling Support](https://github.com/travetto/travetto/tree/main/module/model#readme "Datastore abstraction for core operations."). This source allows the [Data Modeling Support](https://github.com/travetto/travetto/tree/main/module/model#readme "Datastore abstraction for core operations.") module to read, write and query against [elasticsearch](https://elastic.co). In development mode, [ElasticsearchModelService](https://github.com/travetto/travetto/tree/main/module/model-elasticsearch/src/service.ts#L30) will also modify the [elasticsearch](https://elastic.co) schema in real time to minimize impact to development.
17
17
 
18
18
  Supported features:
19
- * [CRUD](https://github.com/travetto/travetto/tree/main/module/model/src/service/crud.ts#L11)
20
- * [Bulk](https://github.com/travetto/travetto/tree/main/module/model/src/service/bulk.ts#L19)
21
- * [Expiry](https://github.com/travetto/travetto/tree/main/module/model/src/service/expiry.ts#L11)
22
- * [Indexed](https://github.com/travetto/travetto/tree/main/module/model/src/service/indexed.ts#L12)
23
- * [Query Crud](https://github.com/travetto/travetto/tree/main/module/model-query/src/service/crud.ts#L11)
24
- * [Facet](https://github.com/travetto/travetto/tree/main/module/model-query/src/service/facet.ts#L12)
25
- * [Query](https://github.com/travetto/travetto/tree/main/module/model-query/src/service/query.ts#L10)
26
- * [Suggest](https://github.com/travetto/travetto/tree/main/module/model-query/src/service/suggest.ts#L12)
19
+ * [CRUD](https://github.com/travetto/travetto/tree/main/module/model/src/types/crud.ts#L11)
20
+ * [Bulk](https://github.com/travetto/travetto/tree/main/module/model/src/types/bulk.ts#L64)
21
+ * [Expiry](https://github.com/travetto/travetto/tree/main/module/model/src/types/expiry.ts#L10)
22
+ * [Indexed](https://github.com/travetto/travetto/tree/main/module/model/src/types/indexed.ts#L11)
23
+ * [Query Crud](https://github.com/travetto/travetto/tree/main/module/model-query/src/types/crud.ts#L11)
24
+ * [Facet](https://github.com/travetto/travetto/tree/main/module/model-query/src/types/facet.ts#L14)
25
+ * [Query](https://github.com/travetto/travetto/tree/main/module/model-query/src/types/query.ts#L10)
26
+ * [Suggest](https://github.com/travetto/travetto/tree/main/module/model-query/src/types/suggest.ts#L12)
27
27
  Out of the box, by installing the module, everything should be wired up by default.If you need to customize any aspect of the source or config, you can override and register it with the [Dependency Injection](https://github.com/travetto/travetto/tree/main/module/di#readme "Dependency registration/management and injection support.") module.
28
28
 
29
29
  **Code: Wiring up a custom Model Source**
@@ -45,15 +45,6 @@ where the [ElasticsearchModelConfig](https://github.com/travetto/travetto/tree/m
45
45
 
46
46
  **Code: Structure of ElasticsearchModelConfig**
47
47
  ```typescript
48
- import { TimeSpan } from '@travetto/runtime';
49
- import { Config } from '@travetto/config';
50
- import { Field } from '@travetto/schema';
51
-
52
- import { EsSchemaConfig } from './internal/types';
53
-
54
- /**
55
- * Elasticsearch model config
56
- */
57
48
  @Config('model.elasticsearch')
58
49
  export class ElasticsearchModelConfig {
59
50
  /**
package/__index__.ts CHANGED
@@ -1,2 +1,2 @@
1
- export * from './src/config';
2
- export * from './src/service';
1
+ export * from './src/config.ts';
2
+ export * from './src/service.ts';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/model-elasticsearch",
3
- "version": "6.0.0-rc.1",
3
+ "version": "6.0.0-rc.2",
4
4
  "description": "Elasticsearch backing for the travetto model module, with real-time modeling support for Elasticsearch mappings.",
5
5
  "keywords": [
6
6
  "elasticsearch",
@@ -27,11 +27,11 @@
27
27
  "directory": "module/model-elasticsearch"
28
28
  },
29
29
  "dependencies": {
30
- "@elastic/elasticsearch": "^8.17.0",
31
- "@travetto/cli": "^6.0.0-rc.1",
32
- "@travetto/config": "^6.0.0-rc.1",
33
- "@travetto/model": "^6.0.0-rc.1",
34
- "@travetto/model-query": "^6.0.0-rc.1"
30
+ "@elastic/elasticsearch": "^8.18.1",
31
+ "@travetto/cli": "^6.0.0-rc.2",
32
+ "@travetto/config": "^6.0.0-rc.2",
33
+ "@travetto/model": "^6.0.0-rc.2",
34
+ "@travetto/model-query": "^6.0.0-rc.2"
35
35
  },
36
36
  "travetto": {
37
37
  "displayName": "Elasticsearch Model Source"
package/src/config.ts CHANGED
@@ -2,7 +2,7 @@ import { TimeSpan } from '@travetto/runtime';
2
2
  import { Config } from '@travetto/config';
3
3
  import { Field } from '@travetto/schema';
4
4
 
5
- import { EsSchemaConfig } from './internal/types';
5
+ import { EsSchemaConfig } from './internal/types.ts';
6
6
 
7
7
  /**
8
8
  * Elasticsearch model config
@@ -1,12 +1,11 @@
1
1
  import { Client, estypes } from '@elastic/elasticsearch';
2
2
 
3
3
  import { Class } from '@travetto/runtime';
4
- import { ModelRegistry, ModelType } from '@travetto/model';
5
- import { ModelStorageSupport } from '@travetto/model/src/service/storage';
4
+ import { ModelRegistry, ModelType, ModelStorageSupport } from '@travetto/model';
6
5
  import { SchemaChange } from '@travetto/schema';
7
6
 
8
- import { ElasticsearchModelConfig } from './config';
9
- import { ElasticsearchSchemaUtil } from './internal/schema';
7
+ import { ElasticsearchModelConfig } from './config.ts';
8
+ import { ElasticsearchSchemaUtil } from './internal/schema.ts';
10
9
 
11
10
  /**
12
11
  * Manager for elasticsearch indices and schemas
@@ -1,14 +1,11 @@
1
1
  import { estypes } from '@elastic/elasticsearch';
2
2
 
3
3
  import { castTo, Class, TypedObject } from '@travetto/runtime';
4
- import { WhereClause, SelectClause, SortClause, Query } from '@travetto/model-query';
5
- import { ModelQueryUtil } from '@travetto/model-query/src/internal/service/query';
6
- import { ModelRegistry } from '@travetto/model/src/registry/model';
7
- import { IndexConfig } from '@travetto/model/src/registry/types';
8
- import { ModelType } from '@travetto/model/src/types/model';
4
+ import { WhereClause, SelectClause, SortClause, Query, ModelQueryUtil } from '@travetto/model-query';
5
+ import { IndexConfig, ModelType, ModelRegistry } from '@travetto/model';
9
6
  import { DataUtil, SchemaRegistry } from '@travetto/schema';
10
7
 
11
- import { EsSchemaConfig } from './types';
8
+ import { EsSchemaConfig } from './types.ts';
12
9
 
13
10
  /**
14
11
  * Support tools for dealing with elasticsearch specific requirements
@@ -1,11 +1,12 @@
1
1
  import { estypes } from '@elastic/elasticsearch';
2
2
 
3
- import { Class } from '@travetto/runtime';
3
+ import { Class, toConcrete } from '@travetto/runtime';
4
4
  import { ModelRegistry } from '@travetto/model';
5
- import { PointImpl } from '@travetto/model-query/src/internal/model/point';
6
- import { DataUtil, SchemaRegistry } from '@travetto/schema';
5
+ import { Point, DataUtil, SchemaRegistry } from '@travetto/schema';
7
6
 
8
- import { EsSchemaConfig } from './types';
7
+ import { EsSchemaConfig } from './types.ts';
8
+
9
+ const PointImpl = toConcrete<Point>();
9
10
 
10
11
  /**
11
12
  * Utils for ES Schema management
package/src/service.ts CHANGED
@@ -2,8 +2,8 @@ import { Client, errors, estypes } from '@elastic/elasticsearch';
2
2
 
3
3
  import {
4
4
  ModelCrudSupport, BulkOp, BulkResponse, ModelBulkSupport, ModelExpirySupport,
5
- ModelIndexedSupport, ModelType, ModelStorageSupport, NotFoundError, ModelRegistry,
6
- OptionalId
5
+ ModelIndexedSupport, ModelType, ModelStorageSupport, NotFoundError, ModelRegistry, OptionalId,
6
+ ModelCrudUtil, ModelIndexedUtil, ModelStorageUtil, ModelExpiryUtil, ModelBulkUtil
7
7
  } from '@travetto/model';
8
8
  import { ShutdownManager, type DeepPartial, type Class, castTo, asFull, TypedObject, asConstructable } from '@travetto/runtime';
9
9
  import { SchemaChange, BindUtil } from '@travetto/schema';
@@ -11,24 +11,17 @@ import { Injectable } from '@travetto/di';
11
11
  import {
12
12
  ModelQuery, ModelQueryCrudSupport, ModelQueryFacetSupport,
13
13
  ModelQuerySupport, PageableModelQuery, Query, ValidStringFields,
14
- QueryVerifier
14
+ QueryVerifier, ModelQuerySuggestSupport,
15
+ ModelQueryUtil, ModelQuerySuggestUtil, ModelQueryCrudUtil,
16
+ ModelQueryFacet,
15
17
  } from '@travetto/model-query';
16
18
 
17
- import { ModelCrudUtil } from '@travetto/model/src/internal/service/crud';
18
- import { ModelIndexedUtil } from '@travetto/model/src/internal/service/indexed';
19
- import { ModelStorageUtil } from '@travetto/model/src/internal/service/storage';
20
- import { ModelQueryUtil } from '@travetto/model-query/src/internal/service/query';
21
- import { ModelQuerySuggestUtil } from '@travetto/model-query/src/internal/service/suggest';
22
- import { ModelExpiryUtil } from '@travetto/model/src/internal/service/expiry';
23
- import { ModelQueryExpiryUtil } from '@travetto/model-query/src/internal/service/expiry';
24
- import { ModelQuerySuggestSupport } from '@travetto/model-query/src/service/suggest';
25
- import { ModelBulkUtil } from '@travetto/model/src/internal/service/bulk';
26
-
27
- import { ElasticsearchModelConfig } from './config';
28
- import { EsBulkError } from './internal/types';
29
- import { ElasticsearchQueryUtil } from './internal/query';
30
- import { ElasticsearchSchemaUtil } from './internal/schema';
31
- import { IndexManager } from './index-manager';
19
+
20
+ import { ElasticsearchModelConfig } from './config.ts';
21
+ import { EsBulkError } from './internal/types.ts';
22
+ import { ElasticsearchQueryUtil } from './internal/query.ts';
23
+ import { ElasticsearchSchemaUtil } from './internal/schema.ts';
24
+ import { IndexManager } from './index-manager.ts';
32
25
 
33
26
  /**
34
27
  * Elasticsearch model source.
@@ -57,12 +50,12 @@ export class ElasticsearchModelService implements
57
50
  query = undefined;
58
51
  }
59
52
  try {
60
- const res = await this.client.search<T>({
53
+ const result = await this.client.search<T>({
61
54
  ...this.manager.getIdentity(cls),
62
55
  ...search,
63
56
  query
64
57
  });
65
- return res;
58
+ return result;
66
59
  } catch (err) {
67
60
  if (err instanceof errors.ResponseError && err.meta.body && typeof err.meta.body === 'object' && 'error' in err.meta.body) {
68
61
  console.error(err.meta.body.error);
@@ -138,8 +131,8 @@ export class ElasticsearchModelService implements
138
131
 
139
132
  async get<T extends ModelType>(cls: Class<T>, id: string): Promise<T> {
140
133
  try {
141
- const res = await this.client.get<T>({ ...this.manager.getIdentity(cls), id });
142
- return this.postLoad(cls, res);
134
+ const result = await this.client.get<T>({ ...this.manager.getIdentity(cls), id });
135
+ return this.postLoad(cls, result);
143
136
  } catch {
144
137
  throw new NotFoundError(cls, id);
145
138
  }
@@ -149,12 +142,12 @@ export class ElasticsearchModelService implements
149
142
  ModelCrudUtil.ensureNotSubType(cls);
150
143
 
151
144
  try {
152
- const res = await this.client.delete({
145
+ const result = await this.client.delete({
153
146
  ...this.manager.getIdentity(cls),
154
147
  id,
155
148
  refresh: true,
156
149
  });
157
- if (res.result === 'not_found') {
150
+ if (result.result === 'not_found') {
158
151
  throw new NotFoundError(cls, id);
159
152
  }
160
153
  } catch (err) {
@@ -299,7 +292,7 @@ export class ElasticsearchModelService implements
299
292
  return acc;
300
293
  }, []);
301
294
 
302
- const res = await this.client.bulk({
295
+ const result = await this.client.bulk({
303
296
  operations: body,
304
297
  refresh: true
305
298
  });
@@ -318,8 +311,8 @@ export class ElasticsearchModelService implements
318
311
 
319
312
  type Count = keyof typeof out['counts'];
320
313
 
321
- for (let i = 0; i < res.items.length; i++) {
322
- const item = res.items[i];
314
+ for (let i = 0; i < result.items.length; i++) {
315
+ const item = result.items[i];
323
316
  const [k] = TypedObject.keys(item);
324
317
  const v = item[k]!;
325
318
  if (v.error) {
@@ -353,27 +346,27 @@ export class ElasticsearchModelService implements
353
346
 
354
347
  // Expiry
355
348
  deleteExpired<T extends ModelType>(cls: Class<T>): Promise<number> {
356
- return ModelQueryExpiryUtil.deleteExpired(this, cls);
349
+ return ModelQueryCrudUtil.deleteExpired(this, cls);
357
350
  }
358
351
 
359
352
  // Indexed
360
353
  async getByIndex<T extends ModelType>(cls: Class<T>, idx: string, body: DeepPartial<T>): Promise<T> {
361
354
  const { key } = ModelIndexedUtil.computeIndexKey(cls, idx, body);
362
- const res = await this.execSearch<T>(cls, {
355
+ const result = await this.execSearch<T>(cls, {
363
356
  query: ElasticsearchQueryUtil.getSearchQuery(cls,
364
357
  ElasticsearchQueryUtil.extractWhereTermQuery(cls,
365
358
  ModelIndexedUtil.projectIndex(cls, idx, body))
366
359
  )
367
360
  });
368
- if (!res.hits.hits.length) {
361
+ if (!result.hits.hits.length) {
369
362
  throw new NotFoundError(`${cls.name}: ${idx}`, key);
370
363
  }
371
- return this.postLoad(cls, res.hits.hits[0]);
364
+ return this.postLoad(cls, result.hits.hits[0]);
372
365
  }
373
366
 
374
367
  async deleteByIndex<T extends ModelType>(cls: Class<T>, idx: string, body: DeepPartial<T>): Promise<void> {
375
368
  const { key } = ModelIndexedUtil.computeIndexKey(cls, idx, body);
376
- const res = await this.client.deleteByQuery({
369
+ const result = await this.client.deleteByQuery({
377
370
  index: this.manager.getIdentity(cls).index,
378
371
  query: ElasticsearchQueryUtil.getSearchQuery(cls,
379
372
  ElasticsearchQueryUtil.extractWhereTermQuery(cls,
@@ -381,7 +374,7 @@ export class ElasticsearchModelService implements
381
374
  ),
382
375
  refresh: true
383
376
  });
384
- if (res.deleted) {
377
+ if (result.deleted) {
385
378
  return;
386
379
  }
387
380
  throw new NotFoundError(`${cls.name}: ${idx}`, key);
@@ -444,8 +437,8 @@ export class ElasticsearchModelService implements
444
437
  await QueryVerifier.verify(cls, query);
445
438
 
446
439
  const req = ElasticsearchQueryUtil.getSearchObject(cls, { ...query, limit: 0 }, this.config.schemaConfig);
447
- const res: number | { value: number } = (await this.execSearch(cls, req)).hits.total || { value: 0 };
448
- return typeof res !== 'number' ? res.value : res;
440
+ const result: number | { value: number } = (await this.execSearch(cls, req)).hits.total || { value: 0 };
441
+ return typeof result !== 'number' ? result.value : result;
449
442
  }
450
443
 
451
444
  // Query Crud
@@ -471,7 +464,7 @@ export class ElasticsearchModelService implements
471
464
  const copy = BindUtil.bindSchemaToObject(cls, asFull<T>({}), item);
472
465
 
473
466
  try {
474
- const res = await this.client.updateByQuery({
467
+ const result = await this.client.updateByQuery({
475
468
  ...this.manager.getIdentity(cls),
476
469
  refresh: true,
477
470
  query: search.query,
@@ -479,7 +472,7 @@ export class ElasticsearchModelService implements
479
472
  script: ElasticsearchSchemaUtil.generateReplaceScript(castTo(copy))
480
473
  });
481
474
 
482
- if (res.version_conflicts || res.updated === undefined || res.updated === 0) {
475
+ if (result.version_conflicts || result.updated === undefined || result.updated === 0) {
483
476
  throw new NotFoundError(cls, id);
484
477
  }
485
478
  } catch (err) {
@@ -497,12 +490,12 @@ export class ElasticsearchModelService implements
497
490
  await QueryVerifier.verify(cls, query);
498
491
 
499
492
  const { sort: _, ...q } = ElasticsearchQueryUtil.getSearchObject(cls, query, this.config.schemaConfig, false);
500
- const res = await this.client.deleteByQuery({
493
+ const result = await this.client.deleteByQuery({
501
494
  ...this.manager.getIdentity(cls),
502
495
  ...q,
503
496
  refresh: true,
504
497
  });
505
- return res.deleted ?? 0;
498
+ return result.deleted ?? 0;
506
499
  }
507
500
 
508
501
  async updatePartialByQuery<T extends ModelType>(cls: Class<T>, query: ModelQuery<T>, data: Partial<T>): Promise<number> {
@@ -512,14 +505,14 @@ export class ElasticsearchModelService implements
512
505
  const script = ElasticsearchSchemaUtil.generateUpdateScript(item);
513
506
 
514
507
  const search = ElasticsearchQueryUtil.getSearchObject(cls, query, this.config.schemaConfig);
515
- const res = await this.client.updateByQuery({
508
+ const result = await this.client.updateByQuery({
516
509
  ...this.manager.getIdentity(cls),
517
510
  refresh: true,
518
511
  query: search.query,
519
512
  script,
520
513
  });
521
514
 
522
- return res.updated ?? 0;
515
+ return result.updated ?? 0;
523
516
  }
524
517
 
525
518
  // Query Facet
@@ -528,8 +521,8 @@ export class ElasticsearchModelService implements
528
521
 
529
522
  const q = ModelQuerySuggestUtil.getSuggestQuery<T>(cls, field, prefix, query);
530
523
  const search = ElasticsearchQueryUtil.getSearchObject(cls, q);
531
- const res = await this.execSearch(cls, search);
532
- const all = await Promise.all(res.hits.hits.map(x => this.postLoad(cls, x)));
524
+ const result = await this.execSearch(cls, search);
525
+ const all = await Promise.all(result.hits.hits.map(x => this.postLoad(cls, x)));
533
526
  return ModelQuerySuggestUtil.combineSuggestResults(cls, field, prefix, all, (x, v) => v, query && query.limit);
534
527
  }
535
528
 
@@ -541,13 +534,13 @@ export class ElasticsearchModelService implements
541
534
  ...query
542
535
  });
543
536
  const search = ElasticsearchQueryUtil.getSearchObject(cls, q);
544
- const res = await this.execSearch(cls, search);
545
- const all = await Promise.all(res.hits.hits.map(x => castTo<T>(({ [field]: field === 'id' ? x._id : x._source![field] }))));
537
+ const result = await this.execSearch(cls, search);
538
+ const all = await Promise.all(result.hits.hits.map(x => castTo<T>(({ [field]: field === 'id' ? x._id : x._source![field] }))));
546
539
  return ModelQuerySuggestUtil.combineSuggestResults(cls, field, prefix, all, x => x, query && query.limit);
547
540
  }
548
541
 
549
542
  // Facet
550
- async facet<T extends ModelType>(cls: Class<T>, field: ValidStringFields<T>, query?: ModelQuery<T>): Promise<{ key: string, count: number }[]> {
543
+ async facet<T extends ModelType>(cls: Class<T>, field: ValidStringFields<T>, query?: ModelQuery<T>): Promise<ModelQueryFacet[]> {
551
544
  await QueryVerifier.verify(cls, query);
552
545
 
553
546
  const q = ElasticsearchQueryUtil.getSearchObject(cls, query ?? {}, this.config.schemaConfig);
@@ -560,8 +553,8 @@ export class ElasticsearchModelService implements
560
553
  size: 0
561
554
  };
562
555
 
563
- const res = await this.execSearch(cls, search);
564
- const { buckets } = castTo<estypes.AggregationsStringTermsAggregate>('buckets' in res.aggregations![field] ? res.aggregations![field] : { buckets: [] });
556
+ const result = await this.execSearch(cls, search);
557
+ const { buckets } = castTo<estypes.AggregationsStringTermsAggregate>('buckets' in result.aggregations![field] ? result.aggregations![field] : { buckets: [] });
565
558
  const out = Array.isArray(buckets) ? buckets.map(b => ({ key: b.key, count: b.doc_count })) : [];
566
559
  return out;
567
560
  }