@travetto/model-query 8.0.0-alpha.9 → 8.0.0
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 +24 -14
- package/__index__.ts +5 -6
- package/package.json +16 -16
- package/src/internal/types.ts +16 -10
- package/src/model/indexes.ts +36 -0
- package/src/model/query.ts +5 -7
- package/src/model/where-clause.ts +31 -29
- package/src/types/crud.ts +4 -4
- package/src/types/facet.ts +5 -5
- package/src/types/query.ts +2 -2
- package/src/types/suggest.ts +15 -5
- package/src/util/crud.ts +2 -2
- package/src/util/facet.ts +2 -2
- package/src/util/query.ts +29 -26
- package/src/util/suggest.ts +28 -11
- package/src/verifier.ts +24 -30
- package/support/doc.support.tsx +6 -7
- package/support/test/crud.ts +90 -52
- package/support/test/facet.ts +23 -15
- package/support/test/model.ts +34 -2
- package/support/test/polymorphism.ts +24 -26
- package/support/test/query.ts +353 -119
- package/support/test/suggest.ts +60 -8
package/support/test/query.ts
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
import assert from 'node:assert';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { type ModelCrudSupport, NotFoundError } from '@travetto/model';
|
|
4
4
|
import { TimeUtil } from '@travetto/runtime';
|
|
5
|
-
import {
|
|
5
|
+
import { Suite, Test } from '@travetto/test';
|
|
6
6
|
|
|
7
7
|
import { BaseModelSuite } from '@travetto/model/support/test/base.ts';
|
|
8
8
|
|
|
9
|
-
import { Aged, Location, Names, Note, Person, SimpleList, WithNestedLists, WithNestedNestedLists } from './model.ts';
|
|
10
|
-
|
|
11
9
|
import type { ModelQuerySupport } from '../../src/types/query.ts';
|
|
10
|
+
import { Aged, Location, Names, Note, Person, PersonFamily, Recipe, SimpleList, WithNestedLists, WithNestedNestedLists } from './model.ts';
|
|
12
11
|
|
|
13
12
|
@Suite()
|
|
14
13
|
export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport & ModelCrudSupport> {
|
|
15
|
-
|
|
16
14
|
supportsGeo = true;
|
|
17
15
|
|
|
18
16
|
@Test()
|
|
19
17
|
async testIds() {
|
|
20
18
|
const svc = await this.service;
|
|
21
19
|
|
|
22
|
-
const people = [1, 2, 3, 8].map(x =>
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
20
|
+
const people = [1, 2, 3, 8].map(x =>
|
|
21
|
+
Person.from({
|
|
22
|
+
id: svc.idSource.create(),
|
|
23
|
+
name: 'Bob Omber',
|
|
24
|
+
age: 20 + x,
|
|
25
|
+
gender: 'm',
|
|
26
|
+
address: {
|
|
27
|
+
street1: 'a',
|
|
28
|
+
...(x === 1 ? { street2: 'b' } : {})
|
|
29
|
+
}
|
|
30
|
+
})
|
|
31
|
+
);
|
|
32
32
|
|
|
33
33
|
await this.saveAll(Person, people);
|
|
34
34
|
|
|
@@ -48,20 +48,25 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
48
48
|
@Test('verify word boundary')
|
|
49
49
|
async testWordBoundary() {
|
|
50
50
|
const service = await this.service;
|
|
51
|
-
await this.saveAll(
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
51
|
+
await this.saveAll(
|
|
52
|
+
Person,
|
|
53
|
+
[1, 2, 3, 8].map(x =>
|
|
54
|
+
Person.from({
|
|
55
|
+
name: 'Bob Omber',
|
|
56
|
+
age: 20 + x,
|
|
57
|
+
gender: 'm',
|
|
58
|
+
address: {
|
|
59
|
+
street1: 'a',
|
|
60
|
+
...(x === 1 ? { street2: 'b' } : {})
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
)
|
|
64
|
+
);
|
|
60
65
|
|
|
61
66
|
const results = await service.query(Person, { where: { name: { $regex: /\bomb.*/i } } });
|
|
62
67
|
assert(results.length === 4);
|
|
63
68
|
|
|
64
|
-
const results2 = await service.query(Person, { where: { name: { $regex: /\
|
|
69
|
+
const results2 = await service.query(Person, { where: { name: { $regex: /\b.?mbo.*/i } } });
|
|
65
70
|
assert(results2.length === 0);
|
|
66
71
|
|
|
67
72
|
const results3 = await service.query(Person, { where: { name: { $regex: /\bomb.*/ } } });
|
|
@@ -71,15 +76,20 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
71
76
|
@Test('verify query one behavior')
|
|
72
77
|
async testQueryOne() {
|
|
73
78
|
const service = await this.service;
|
|
74
|
-
await this.saveAll(
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
79
|
+
await this.saveAll(
|
|
80
|
+
Person,
|
|
81
|
+
[1, 2, 3, 8].map(x =>
|
|
82
|
+
Person.from({
|
|
83
|
+
name: 'Bob Omber',
|
|
84
|
+
age: 20 + x,
|
|
85
|
+
gender: 'm',
|
|
86
|
+
address: {
|
|
87
|
+
street1: 'a',
|
|
88
|
+
...(x === 1 ? { street2: 'b' } : {})
|
|
89
|
+
}
|
|
90
|
+
})
|
|
91
|
+
)
|
|
92
|
+
);
|
|
83
93
|
|
|
84
94
|
await assert.rejects(() => service.queryOne(Person, { where: { gender: 'm' } }), /Invalid number of results/);
|
|
85
95
|
await assert.rejects(() => service.queryOne(Person, { where: { gender: 'z' } }), NotFoundError);
|
|
@@ -91,13 +101,19 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
91
101
|
@Test('Verify array $in queries work properly')
|
|
92
102
|
async testArrayContains() {
|
|
93
103
|
const svc = await this.service;
|
|
94
|
-
const first = await svc.create(
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
104
|
+
const first = await svc.create(
|
|
105
|
+
SimpleList,
|
|
106
|
+
SimpleList.from({
|
|
107
|
+
names: ['a', 'b', 'c']
|
|
108
|
+
})
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
const second = await svc.create(
|
|
112
|
+
SimpleList,
|
|
113
|
+
SimpleList.from({
|
|
114
|
+
names: ['b', 'c', 'd']
|
|
115
|
+
})
|
|
116
|
+
);
|
|
101
117
|
|
|
102
118
|
const single = await svc.query(SimpleList, {
|
|
103
119
|
where: {
|
|
@@ -154,6 +170,62 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
154
170
|
assert(idNin.length === 2);
|
|
155
171
|
}
|
|
156
172
|
|
|
173
|
+
@Test('Verify list intersection queries')
|
|
174
|
+
async testListIntersection() {
|
|
175
|
+
const service = await this.service;
|
|
176
|
+
|
|
177
|
+
await this.saveAll(SimpleList, [
|
|
178
|
+
SimpleList.from({
|
|
179
|
+
names: ['apple', 'banana']
|
|
180
|
+
}),
|
|
181
|
+
SimpleList.from({
|
|
182
|
+
names: ['banana', 'cherry']
|
|
183
|
+
}),
|
|
184
|
+
SimpleList.from({
|
|
185
|
+
names: ['cherry', 'date']
|
|
186
|
+
}),
|
|
187
|
+
SimpleList.from({
|
|
188
|
+
names: ['elderberry']
|
|
189
|
+
})
|
|
190
|
+
]);
|
|
191
|
+
|
|
192
|
+
const singleMatch = await service.query(SimpleList, {
|
|
193
|
+
where: {
|
|
194
|
+
names: {
|
|
195
|
+
$in: ['apple']
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
assert(singleMatch.length === 1);
|
|
200
|
+
|
|
201
|
+
const intersectionMatch = await service.query(SimpleList, {
|
|
202
|
+
where: {
|
|
203
|
+
names: {
|
|
204
|
+
$in: ['banana', 'cherry']
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
assert(intersectionMatch.length === 3);
|
|
209
|
+
|
|
210
|
+
const disjointIntersectionMatch = await service.query(SimpleList, {
|
|
211
|
+
where: {
|
|
212
|
+
names: {
|
|
213
|
+
$in: ['apple', 'date']
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
assert(disjointIntersectionMatch.length === 2);
|
|
218
|
+
|
|
219
|
+
const noIntersectionMatch = await service.query(SimpleList, {
|
|
220
|
+
where: {
|
|
221
|
+
names: {
|
|
222
|
+
$in: ['fig', 'grape']
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
assert(noIntersectionMatch.length === 0);
|
|
227
|
+
}
|
|
228
|
+
|
|
157
229
|
@Test('verify all operators')
|
|
158
230
|
async testArrayAll() {
|
|
159
231
|
const service = await this.service;
|
|
@@ -161,7 +233,7 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
161
233
|
await this.saveAll(Names, [
|
|
162
234
|
Names.from({ values: ['a', 'b', 'c'] }),
|
|
163
235
|
Names.from({ values: ['a', 'b'] }),
|
|
164
|
-
Names.from({ values: ['b', 'c'] })
|
|
236
|
+
Names.from({ values: ['b', 'c'] })
|
|
165
237
|
]);
|
|
166
238
|
|
|
167
239
|
const results = await service.query(Names, {});
|
|
@@ -212,23 +284,27 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
212
284
|
async testSorting() {
|
|
213
285
|
const service = await this.service;
|
|
214
286
|
|
|
215
|
-
const people = [1, 2, 3, 8].map(x =>
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
287
|
+
const people = [1, 2, 3, 8].map(x =>
|
|
288
|
+
Person.from({
|
|
289
|
+
id: service.idSource.create(),
|
|
290
|
+
name: 'Bob',
|
|
291
|
+
age: 20 + x,
|
|
292
|
+
gender: 'm',
|
|
293
|
+
address: {
|
|
294
|
+
street1: 'a',
|
|
295
|
+
...(x === 1 ? { street2: 'b' } : {})
|
|
296
|
+
}
|
|
297
|
+
})
|
|
298
|
+
);
|
|
225
299
|
|
|
226
300
|
await this.saveAll(Person, people);
|
|
227
301
|
|
|
228
302
|
const all = await service.query(Person, {
|
|
229
|
-
sort: [
|
|
230
|
-
|
|
231
|
-
|
|
303
|
+
sort: [
|
|
304
|
+
{
|
|
305
|
+
age: -1
|
|
306
|
+
}
|
|
307
|
+
]
|
|
232
308
|
});
|
|
233
309
|
assert(all[0].age >= all[1].age);
|
|
234
310
|
}
|
|
@@ -243,23 +319,30 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
243
319
|
|
|
244
320
|
const toAdd = [];
|
|
245
321
|
|
|
246
|
-
for (let i = 0; i < 5; i
|
|
247
|
-
for (let j = 0; j < 5; j
|
|
248
|
-
toAdd.push(
|
|
249
|
-
|
|
250
|
-
|
|
322
|
+
for (let i = 0; i < 5; i += 1) {
|
|
323
|
+
for (let j = 0; j < 5; j += 1) {
|
|
324
|
+
toAdd.push(
|
|
325
|
+
Location.from({
|
|
326
|
+
point: [i, j]
|
|
327
|
+
})
|
|
328
|
+
);
|
|
251
329
|
}
|
|
252
330
|
}
|
|
253
331
|
|
|
254
332
|
await this.saveAll(Location, toAdd);
|
|
255
333
|
|
|
256
|
-
assert(await svc.queryCount(Location, {}) === 25);
|
|
334
|
+
assert((await svc.queryCount(Location, {})) === 25);
|
|
257
335
|
|
|
258
336
|
const result = await svc.query(Location, {
|
|
259
337
|
limit: 100,
|
|
260
338
|
where: {
|
|
261
339
|
point: {
|
|
262
|
-
$geoWithin: [
|
|
340
|
+
$geoWithin: [
|
|
341
|
+
[-1, -1],
|
|
342
|
+
[-1, 6],
|
|
343
|
+
[6, 6],
|
|
344
|
+
[6, -1]
|
|
345
|
+
]
|
|
263
346
|
}
|
|
264
347
|
}
|
|
265
348
|
});
|
|
@@ -286,15 +369,18 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
286
369
|
|
|
287
370
|
const id = service.idSource.create();
|
|
288
371
|
|
|
289
|
-
await service.create(
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
372
|
+
await service.create(
|
|
373
|
+
Note,
|
|
374
|
+
Note.from({
|
|
375
|
+
id,
|
|
376
|
+
entities: [
|
|
377
|
+
{
|
|
378
|
+
label: 'hi',
|
|
379
|
+
id
|
|
380
|
+
}
|
|
381
|
+
]
|
|
382
|
+
})
|
|
383
|
+
);
|
|
298
384
|
|
|
299
385
|
const out = await service.queryCount(Note, {
|
|
300
386
|
where: {
|
|
@@ -320,9 +406,12 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
320
406
|
@Test()
|
|
321
407
|
async verifyDateRange() {
|
|
322
408
|
const service = await this.service;
|
|
323
|
-
await this.saveAll(
|
|
324
|
-
Aged
|
|
325
|
-
|
|
409
|
+
await this.saveAll(
|
|
410
|
+
Aged,
|
|
411
|
+
(['-5d', '-4d', '-3d', '-2d', '-1d', '0d', '1d', '2d', '3d', '4d', '5d'] as const).map(delta =>
|
|
412
|
+
Aged.from({ createdAt: TimeUtil.fromNow(delta) })
|
|
413
|
+
)
|
|
414
|
+
);
|
|
326
415
|
|
|
327
416
|
const simple = await service.queryCount(Aged, {
|
|
328
417
|
where: {
|
|
@@ -366,28 +455,13 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
366
455
|
@Test()
|
|
367
456
|
async verifyArrayEmptyVsNot() {
|
|
368
457
|
const service = await this.service;
|
|
369
|
-
await
|
|
370
|
-
tags: ['a', 'b']
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
names: [
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
await service.create(WithNestedLists, {
|
|
378
|
-
names: ['c', 'd'],
|
|
379
|
-
tags: ['e', 'f']
|
|
380
|
-
});
|
|
381
|
-
|
|
382
|
-
await service.create(WithNestedLists, {
|
|
383
|
-
names: ['g', 'h'],
|
|
384
|
-
tags: []
|
|
385
|
-
});
|
|
386
|
-
|
|
387
|
-
await service.create(WithNestedLists, {
|
|
388
|
-
names: [],
|
|
389
|
-
tags: []
|
|
390
|
-
});
|
|
458
|
+
await this.saveAll(WithNestedLists, [
|
|
459
|
+
WithNestedLists.from({ tags: ['a', 'b'] }),
|
|
460
|
+
WithNestedLists.from({ names: ['c', 'd'] }),
|
|
461
|
+
WithNestedLists.from({ names: ['c', 'd'], tags: ['e', 'f'] }),
|
|
462
|
+
WithNestedLists.from({ names: ['g', 'h'], tags: [] }),
|
|
463
|
+
WithNestedLists.from({ names: [], tags: [] })
|
|
464
|
+
]);
|
|
391
465
|
|
|
392
466
|
let total = await service.queryCount(WithNestedLists, {
|
|
393
467
|
where: {
|
|
@@ -395,6 +469,7 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
395
469
|
}
|
|
396
470
|
});
|
|
397
471
|
assert(total === 3);
|
|
472
|
+
|
|
398
473
|
total = await service.queryCount(WithNestedLists, {
|
|
399
474
|
where: {
|
|
400
475
|
names: { $exists: false }
|
|
@@ -430,35 +505,20 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
430
505
|
names: { $exists: true }
|
|
431
506
|
}
|
|
432
507
|
});
|
|
433
|
-
|
|
434
508
|
assert(total === 1);
|
|
435
509
|
}
|
|
436
510
|
|
|
437
511
|
@Test()
|
|
438
512
|
async verifyNestedArrayEmptyVsNot() {
|
|
439
513
|
const service = await this.service;
|
|
440
|
-
await service.create(WithNestedNestedLists, {
|
|
441
|
-
tags: ['a', 'b']
|
|
442
|
-
});
|
|
443
|
-
|
|
444
|
-
await service.create(WithNestedNestedLists, {
|
|
445
|
-
sub: { names: ['c', 'd'] },
|
|
446
|
-
});
|
|
447
514
|
|
|
448
|
-
await
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
tags: []
|
|
456
|
-
});
|
|
457
|
-
|
|
458
|
-
await service.create(WithNestedNestedLists, {
|
|
459
|
-
sub: {},
|
|
460
|
-
tags: []
|
|
461
|
-
});
|
|
515
|
+
await this.saveAll(WithNestedNestedLists, [
|
|
516
|
+
WithNestedNestedLists.from({ tags: ['a', 'b'] }),
|
|
517
|
+
WithNestedNestedLists.from({ sub: { names: ['c', 'd'] } }),
|
|
518
|
+
WithNestedNestedLists.from({ sub: { names: ['c', 'd'] }, tags: ['e', 'f'] }),
|
|
519
|
+
WithNestedNestedLists.from({ sub: { names: ['g', 'h'] }, tags: [] }),
|
|
520
|
+
WithNestedNestedLists.from({ sub: {}, tags: [] })
|
|
521
|
+
]);
|
|
462
522
|
|
|
463
523
|
let total = await service.queryCount(WithNestedNestedLists, {
|
|
464
524
|
where: {
|
|
@@ -466,6 +526,7 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
466
526
|
}
|
|
467
527
|
});
|
|
468
528
|
assert(total === 3);
|
|
529
|
+
|
|
469
530
|
total = await service.queryCount(WithNestedNestedLists, {
|
|
470
531
|
where: {
|
|
471
532
|
sub: { names: { $exists: false } }
|
|
@@ -504,5 +565,178 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
504
565
|
|
|
505
566
|
assert(total === 1);
|
|
506
567
|
}
|
|
507
|
-
}
|
|
508
568
|
|
|
569
|
+
@Test('Verify queries on nested arrays of schemas')
|
|
570
|
+
async verifyNestedArraySchemaQuery() {
|
|
571
|
+
const service = await this.service;
|
|
572
|
+
|
|
573
|
+
await this.saveAll(Recipe, [
|
|
574
|
+
Recipe.from({
|
|
575
|
+
sections: [{ ingredients: [{ name: 'garlic' }, { name: 'onion' }] }]
|
|
576
|
+
}),
|
|
577
|
+
Recipe.from({
|
|
578
|
+
sections: [{ ingredients: [{ name: 'paprika' }, { name: 'salt' }] }]
|
|
579
|
+
}),
|
|
580
|
+
Recipe.from({
|
|
581
|
+
sections: [{ ingredients: [{ name: 'garlic' }, { name: 'thyme' }] }]
|
|
582
|
+
})
|
|
583
|
+
]);
|
|
584
|
+
|
|
585
|
+
const matchSingle = await service.query(Recipe, {
|
|
586
|
+
where: {
|
|
587
|
+
sections: { ingredients: { name: 'garlic' } }
|
|
588
|
+
}
|
|
589
|
+
});
|
|
590
|
+
assert(matchSingle.length === 2);
|
|
591
|
+
|
|
592
|
+
const matchIn = await service.query(Recipe, {
|
|
593
|
+
where: {
|
|
594
|
+
sections: { ingredients: { name: { $in: ['onion', 'salt'] } } }
|
|
595
|
+
}
|
|
596
|
+
});
|
|
597
|
+
assert(matchIn.length === 2);
|
|
598
|
+
|
|
599
|
+
const matchNotEqual = await service.query(Recipe, {
|
|
600
|
+
where: {
|
|
601
|
+
sections: { ingredients: { name: { $ne: 'garlic' } } }
|
|
602
|
+
}
|
|
603
|
+
});
|
|
604
|
+
assert(matchNotEqual.length === 1);
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
@Test('Verify array of objects property queries')
|
|
608
|
+
async verifyArrayOfObjectsProperty() {
|
|
609
|
+
const service = await this.service;
|
|
610
|
+
|
|
611
|
+
await this.saveAll(Note, [
|
|
612
|
+
Note.from({
|
|
613
|
+
entities: [
|
|
614
|
+
{ id: '1', label: 'one' },
|
|
615
|
+
{ id: '2', label: 'two' }
|
|
616
|
+
]
|
|
617
|
+
}),
|
|
618
|
+
Note.from({
|
|
619
|
+
entities: [
|
|
620
|
+
{ id: '3', label: 'three' },
|
|
621
|
+
{ id: '4', label: 'four' }
|
|
622
|
+
]
|
|
623
|
+
}),
|
|
624
|
+
Note.from({
|
|
625
|
+
entities: [{ id: '5', label: 'five' }]
|
|
626
|
+
})
|
|
627
|
+
]);
|
|
628
|
+
|
|
629
|
+
const inResults = await service.query(Note, {
|
|
630
|
+
where: {
|
|
631
|
+
entities: {
|
|
632
|
+
label: {
|
|
633
|
+
$in: ['one', 'four', 'missing']
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
});
|
|
638
|
+
assert(inResults.length === 2);
|
|
639
|
+
|
|
640
|
+
const eqResults = await service.query(Note, {
|
|
641
|
+
where: {
|
|
642
|
+
entities: {
|
|
643
|
+
label: 'five'
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
});
|
|
647
|
+
assert(eqResults.length === 1);
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
@Test('Verify nested object array property queries')
|
|
651
|
+
async verifyNestedObjectArrayProperty() {
|
|
652
|
+
const service = await this.service;
|
|
653
|
+
|
|
654
|
+
await this.saveAll(PersonFamily, [
|
|
655
|
+
PersonFamily.from({
|
|
656
|
+
family: { children: [{ name: 'one' }, { name: 'two' }] }
|
|
657
|
+
}),
|
|
658
|
+
PersonFamily.from({
|
|
659
|
+
family: { children: [{ name: 'three' }, { name: 'four' }] }
|
|
660
|
+
}),
|
|
661
|
+
PersonFamily.from({
|
|
662
|
+
family: { children: [{ name: 'five' }] }
|
|
663
|
+
})
|
|
664
|
+
]);
|
|
665
|
+
|
|
666
|
+
const inResults = await service.query(PersonFamily, {
|
|
667
|
+
where: {
|
|
668
|
+
family: {
|
|
669
|
+
children: {
|
|
670
|
+
name: {
|
|
671
|
+
$in: ['one', 'two', 'three']
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
});
|
|
677
|
+
assert(inResults.length === 2);
|
|
678
|
+
|
|
679
|
+
const eqResults = await service.query(PersonFamily, {
|
|
680
|
+
where: {
|
|
681
|
+
family: {
|
|
682
|
+
children: {
|
|
683
|
+
name: 'five'
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
});
|
|
688
|
+
assert(eqResults.length === 1);
|
|
689
|
+
|
|
690
|
+
const neResults = await service.query(PersonFamily, {
|
|
691
|
+
where: {
|
|
692
|
+
family: {
|
|
693
|
+
children: {
|
|
694
|
+
name: {
|
|
695
|
+
$ne: 'five'
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
});
|
|
701
|
+
assert(neResults.length === 2);
|
|
702
|
+
|
|
703
|
+
const ninResults = await service.query(PersonFamily, {
|
|
704
|
+
where: {
|
|
705
|
+
family: {
|
|
706
|
+
children: {
|
|
707
|
+
name: {
|
|
708
|
+
$nin: ['one', 'two']
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
});
|
|
714
|
+
assert(ninResults.length === 2);
|
|
715
|
+
|
|
716
|
+
const allResults = await service.query(PersonFamily, {
|
|
717
|
+
where: {
|
|
718
|
+
family: {
|
|
719
|
+
children: {
|
|
720
|
+
name: {
|
|
721
|
+
$all: ['one', 'two']
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
});
|
|
727
|
+
assert(allResults.length === 1);
|
|
728
|
+
|
|
729
|
+
const existsResults = await service.query(PersonFamily, {
|
|
730
|
+
where: {
|
|
731
|
+
family: {
|
|
732
|
+
children: {
|
|
733
|
+
name: {
|
|
734
|
+
$exists: true
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
});
|
|
740
|
+
assert(existsResults.length === 3);
|
|
741
|
+
}
|
|
742
|
+
}
|