elasticlink 0.3.0-beta → 0.4.0-beta

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.
Files changed (109) hide show
  1. package/README.md +61 -14
  2. package/dist/__tests__/aggregation-builder.test.d.ts +2 -0
  3. package/dist/__tests__/aggregation-builder.test.d.ts.map +1 -0
  4. package/dist/__tests__/aggregation-builder.test.js +622 -0
  5. package/dist/__tests__/bulk.test.d.ts +2 -0
  6. package/dist/__tests__/bulk.test.d.ts.map +1 -0
  7. package/dist/__tests__/bulk.test.js +679 -0
  8. package/dist/__tests__/examples.test.d.ts +2 -0
  9. package/dist/__tests__/examples.test.d.ts.map +1 -0
  10. package/dist/__tests__/examples.test.js +2123 -0
  11. package/dist/__tests__/fixtures/finance.d.ts +58 -0
  12. package/dist/__tests__/fixtures/finance.d.ts.map +1 -0
  13. package/dist/__tests__/fixtures/finance.js +73 -0
  14. package/dist/__tests__/fixtures/legal.d.ts +14 -0
  15. package/dist/__tests__/fixtures/legal.d.ts.map +1 -0
  16. package/dist/__tests__/fixtures/legal.js +27 -0
  17. package/dist/__tests__/fixtures/real-estate.d.ts +31 -0
  18. package/dist/__tests__/fixtures/real-estate.d.ts.map +1 -0
  19. package/dist/__tests__/fixtures/real-estate.js +39 -0
  20. package/dist/__tests__/index-management.test.d.ts +2 -0
  21. package/dist/__tests__/index-management.test.d.ts.map +1 -0
  22. package/dist/__tests__/index-management.test.js +1699 -0
  23. package/dist/__tests__/integration/aggregation.integration.test.d.ts +2 -0
  24. package/dist/__tests__/integration/aggregation.integration.test.d.ts.map +1 -0
  25. package/dist/__tests__/integration/aggregation.integration.test.js +188 -0
  26. package/dist/__tests__/integration/bulk.integration.test.d.ts +2 -0
  27. package/dist/__tests__/integration/bulk.integration.test.d.ts.map +1 -0
  28. package/dist/__tests__/integration/bulk.integration.test.js +90 -0
  29. package/dist/__tests__/integration/fixtures/finance.d.ts +37 -0
  30. package/dist/__tests__/integration/fixtures/finance.d.ts.map +1 -0
  31. package/dist/__tests__/integration/fixtures/finance.js +58 -0
  32. package/dist/__tests__/integration/fixtures/legal.d.ts +38 -0
  33. package/dist/__tests__/integration/fixtures/legal.d.ts.map +1 -0
  34. package/dist/__tests__/integration/fixtures/legal.js +65 -0
  35. package/dist/__tests__/integration/fixtures/real-estate.d.ts +17 -0
  36. package/dist/__tests__/integration/fixtures/real-estate.d.ts.map +1 -0
  37. package/dist/__tests__/integration/fixtures/real-estate.js +28 -0
  38. package/dist/__tests__/integration/helpers.d.ts +15 -0
  39. package/dist/__tests__/integration/helpers.d.ts.map +1 -0
  40. package/dist/__tests__/integration/helpers.js +21 -0
  41. package/dist/__tests__/integration/index-management.integration.test.d.ts +2 -0
  42. package/dist/__tests__/integration/index-management.integration.test.d.ts.map +1 -0
  43. package/dist/__tests__/integration/index-management.integration.test.js +67 -0
  44. package/dist/__tests__/integration/multi-search.integration.test.d.ts +2 -0
  45. package/dist/__tests__/integration/multi-search.integration.test.d.ts.map +1 -0
  46. package/dist/__tests__/integration/multi-search.integration.test.js +49 -0
  47. package/dist/__tests__/integration/query.integration.test.d.ts +2 -0
  48. package/dist/__tests__/integration/query.integration.test.d.ts.map +1 -0
  49. package/dist/__tests__/integration/query.integration.test.js +101 -0
  50. package/dist/__tests__/integration/suggester.integration.test.d.ts +2 -0
  51. package/dist/__tests__/integration/suggester.integration.test.d.ts.map +1 -0
  52. package/dist/__tests__/integration/suggester.integration.test.js +42 -0
  53. package/dist/__tests__/multi-search.test.d.ts +2 -0
  54. package/dist/__tests__/multi-search.test.d.ts.map +1 -0
  55. package/dist/__tests__/multi-search.test.js +325 -0
  56. package/dist/__tests__/query-builder-extensions.test.d.ts +2 -0
  57. package/dist/__tests__/query-builder-extensions.test.d.ts.map +1 -0
  58. package/dist/__tests__/query-builder-extensions.test.js +436 -0
  59. package/dist/__tests__/query-builder.test.d.ts +2 -0
  60. package/dist/__tests__/query-builder.test.d.ts.map +1 -0
  61. package/dist/__tests__/query-builder.test.js +5482 -0
  62. package/dist/__tests__/settings-presets.test.d.ts +2 -0
  63. package/dist/__tests__/settings-presets.test.d.ts.map +1 -0
  64. package/dist/__tests__/settings-presets.test.js +183 -0
  65. package/dist/__tests__/suggester.test.d.ts +2 -0
  66. package/dist/__tests__/suggester.test.d.ts.map +1 -0
  67. package/dist/__tests__/suggester.test.js +1006 -0
  68. package/dist/aggregation.builder.d.ts.map +1 -1
  69. package/dist/aggregation.builder.js +101 -94
  70. package/dist/aggregation.types.d.ts +10 -9
  71. package/dist/aggregation.types.d.ts.map +1 -1
  72. package/dist/bulk.builder.d.ts +11 -1
  73. package/dist/bulk.builder.d.ts.map +1 -1
  74. package/dist/bulk.builder.js +10 -11
  75. package/dist/bulk.types.d.ts.map +1 -1
  76. package/dist/field.helpers.d.ts +59 -4
  77. package/dist/field.helpers.d.ts.map +1 -1
  78. package/dist/field.helpers.js +87 -4
  79. package/dist/field.types.d.ts +78 -1
  80. package/dist/field.types.d.ts.map +1 -1
  81. package/dist/index-management.builder.d.ts +15 -3
  82. package/dist/index-management.builder.d.ts.map +1 -1
  83. package/dist/index-management.builder.js +32 -8
  84. package/dist/index-management.types.d.ts +27 -3
  85. package/dist/index-management.types.d.ts.map +1 -1
  86. package/dist/index.d.ts +3 -2
  87. package/dist/index.d.ts.map +1 -1
  88. package/dist/index.js +3 -1
  89. package/dist/mapping.builder.d.ts +16 -3
  90. package/dist/mapping.builder.d.ts.map +1 -1
  91. package/dist/mapping.builder.js +22 -7
  92. package/dist/mapping.types.d.ts +29 -6
  93. package/dist/mapping.types.d.ts.map +1 -1
  94. package/dist/multi-search.builder.d.ts +1 -1
  95. package/dist/multi-search.builder.d.ts.map +1 -1
  96. package/dist/multi-search.builder.js +5 -3
  97. package/dist/query.builder.d.ts +0 -4
  98. package/dist/query.builder.d.ts.map +1 -1
  99. package/dist/query.builder.js +104 -183
  100. package/dist/query.types.d.ts +59 -5
  101. package/dist/query.types.d.ts.map +1 -1
  102. package/dist/settings.presets.d.ts +98 -0
  103. package/dist/settings.presets.d.ts.map +1 -0
  104. package/dist/settings.presets.js +115 -0
  105. package/dist/suggester.builder.d.ts.map +1 -1
  106. package/dist/suggester.builder.js +1 -0
  107. package/dist/suggester.types.d.ts.map +1 -1
  108. package/dist/vector.types.d.ts.map +1 -1
  109. package/package.json +6 -3
@@ -0,0 +1,1006 @@
1
+ import { query, suggest, mappings, keyword, text, float, completion } from '..';
2
+ const matterWithSuggestMappings = mappings({
3
+ matter_id: keyword(),
4
+ title: text(),
5
+ practice_area: keyword(),
6
+ billing_rate: float(),
7
+ title_suggest: completion()
8
+ });
9
+ describe('Suggester API', () => {
10
+ describe('Builder behavior', () => {
11
+ it('should return empty suggest object for empty build', () => {
12
+ const result = suggest(matterWithSuggestMappings).build();
13
+ expect(result).toMatchInlineSnapshot(`
14
+ {
15
+ "suggest": {},
16
+ }
17
+ `);
18
+ });
19
+ it('should overwrite suggester when same name is used twice', () => {
20
+ const result = suggest(matterWithSuggestMappings)
21
+ .term('spell-check', 'acquistion', { field: 'title' })
22
+ .term('spell-check', 'corprate', { field: 'practice_area' })
23
+ .build();
24
+ expect(result).toMatchInlineSnapshot(`
25
+ {
26
+ "suggest": {
27
+ "spell-check": {
28
+ "term": {
29
+ "field": "practice_area",
30
+ },
31
+ "text": "corprate",
32
+ },
33
+ },
34
+ }
35
+ `);
36
+ });
37
+ });
38
+ describe('Term Suggester', () => {
39
+ it('should build basic term suggester', () => {
40
+ const result = suggest(matterWithSuggestMappings)
41
+ .term('name-suggestions', 'acquistion', {
42
+ field: 'title'
43
+ })
44
+ .build();
45
+ expect(result).toMatchInlineSnapshot(`
46
+ {
47
+ "suggest": {
48
+ "name-suggestions": {
49
+ "term": {
50
+ "field": "title",
51
+ },
52
+ "text": "acquistion",
53
+ },
54
+ },
55
+ }
56
+ `);
57
+ });
58
+ it('should build term suggester with size', () => {
59
+ const result = suggest(matterWithSuggestMappings)
60
+ .term('name-suggestions', 'acquistion', {
61
+ field: 'title',
62
+ size: 5
63
+ })
64
+ .build();
65
+ expect(result).toMatchInlineSnapshot(`
66
+ {
67
+ "suggest": {
68
+ "name-suggestions": {
69
+ "term": {
70
+ "field": "title",
71
+ "size": 5,
72
+ },
73
+ "text": "acquistion",
74
+ },
75
+ },
76
+ }
77
+ `);
78
+ });
79
+ it('should build term suggester with suggest_mode', () => {
80
+ const result = suggest(matterWithSuggestMappings)
81
+ .term('name-suggestions', 'acquistion', {
82
+ field: 'title',
83
+ suggest_mode: 'popular'
84
+ })
85
+ .build();
86
+ expect(result).toMatchInlineSnapshot(`
87
+ {
88
+ "suggest": {
89
+ "name-suggestions": {
90
+ "term": {
91
+ "field": "title",
92
+ "suggest_mode": "popular",
93
+ },
94
+ "text": "acquistion",
95
+ },
96
+ },
97
+ }
98
+ `);
99
+ });
100
+ it('should build term suggester with string_distance', () => {
101
+ const result = suggest(matterWithSuggestMappings)
102
+ .term('name-suggestions', 'acquistion', {
103
+ field: 'title',
104
+ string_distance: 'levenshtein'
105
+ })
106
+ .build();
107
+ expect(result).toMatchInlineSnapshot(`
108
+ {
109
+ "suggest": {
110
+ "name-suggestions": {
111
+ "term": {
112
+ "field": "title",
113
+ "string_distance": "levenshtein",
114
+ },
115
+ "text": "acquistion",
116
+ },
117
+ },
118
+ }
119
+ `);
120
+ });
121
+ it('should build term suggester with max_edits', () => {
122
+ const result = suggest(matterWithSuggestMappings)
123
+ .term('name-suggestions', 'acquistion', {
124
+ field: 'title',
125
+ max_edits: 2
126
+ })
127
+ .build();
128
+ expect(result).toMatchInlineSnapshot(`
129
+ {
130
+ "suggest": {
131
+ "name-suggestions": {
132
+ "term": {
133
+ "field": "title",
134
+ "max_edits": 2,
135
+ },
136
+ "text": "acquistion",
137
+ },
138
+ },
139
+ }
140
+ `);
141
+ });
142
+ it('should build term suggester with sort option', () => {
143
+ const result = suggest(matterWithSuggestMappings)
144
+ .term('name-suggestions', 'acquistion', {
145
+ field: 'title',
146
+ sort: 'frequency'
147
+ })
148
+ .build();
149
+ expect(result).toMatchInlineSnapshot(`
150
+ {
151
+ "suggest": {
152
+ "name-suggestions": {
153
+ "term": {
154
+ "field": "title",
155
+ "sort": "frequency",
156
+ },
157
+ "text": "acquistion",
158
+ },
159
+ },
160
+ }
161
+ `);
162
+ });
163
+ it('should build term suggester with prefix_length option', () => {
164
+ const result = suggest(matterWithSuggestMappings)
165
+ .term('name-suggestions', 'acquistion', {
166
+ field: 'title',
167
+ prefix_length: 3
168
+ })
169
+ .build();
170
+ expect(result).toMatchInlineSnapshot(`
171
+ {
172
+ "suggest": {
173
+ "name-suggestions": {
174
+ "term": {
175
+ "field": "title",
176
+ "prefix_length": 3,
177
+ },
178
+ "text": "acquistion",
179
+ },
180
+ },
181
+ }
182
+ `);
183
+ });
184
+ it('should build term suggester with all options', () => {
185
+ const result = suggest(matterWithSuggestMappings)
186
+ .term('name-suggestions', 'acquistion', {
187
+ field: 'title',
188
+ size: 5,
189
+ sort: 'score',
190
+ suggest_mode: 'popular',
191
+ max_edits: 2,
192
+ prefix_length: 1,
193
+ min_word_length: 4,
194
+ min_doc_freq: 0.01
195
+ })
196
+ .build();
197
+ expect(result).toMatchInlineSnapshot(`
198
+ {
199
+ "suggest": {
200
+ "name-suggestions": {
201
+ "term": {
202
+ "field": "title",
203
+ "max_edits": 2,
204
+ "min_doc_freq": 0.01,
205
+ "min_word_length": 4,
206
+ "prefix_length": 1,
207
+ "size": 5,
208
+ "sort": "score",
209
+ "suggest_mode": "popular",
210
+ },
211
+ "text": "acquistion",
212
+ },
213
+ },
214
+ }
215
+ `);
216
+ });
217
+ });
218
+ describe('Phrase Suggester', () => {
219
+ it('should build basic phrase suggester', () => {
220
+ const result = suggest(matterWithSuggestMappings)
221
+ .phrase('description-suggestions', 'powerfull laptop', {
222
+ field: 'title'
223
+ })
224
+ .build();
225
+ expect(result).toMatchInlineSnapshot(`
226
+ {
227
+ "suggest": {
228
+ "description-suggestions": {
229
+ "phrase": {
230
+ "field": "title",
231
+ },
232
+ "text": "powerfull laptop",
233
+ },
234
+ },
235
+ }
236
+ `);
237
+ });
238
+ it('should build phrase suggester with confidence', () => {
239
+ const result = suggest(matterWithSuggestMappings)
240
+ .phrase('description-suggestions', 'powerfull laptop', {
241
+ field: 'title',
242
+ confidence: 2.0
243
+ })
244
+ .build();
245
+ expect(result).toMatchInlineSnapshot(`
246
+ {
247
+ "suggest": {
248
+ "description-suggestions": {
249
+ "phrase": {
250
+ "confidence": 2,
251
+ "field": "title",
252
+ },
253
+ "text": "powerfull laptop",
254
+ },
255
+ },
256
+ }
257
+ `);
258
+ });
259
+ it('should build phrase suggester with direct_generator', () => {
260
+ const result = suggest(matterWithSuggestMappings)
261
+ .phrase('description-suggestions', 'powerfull laptop', {
262
+ field: 'title',
263
+ direct_generator: [
264
+ {
265
+ field: 'title',
266
+ suggest_mode: 'always',
267
+ min_word_length: 1
268
+ }
269
+ ]
270
+ })
271
+ .build();
272
+ expect(result).toMatchInlineSnapshot(`
273
+ {
274
+ "suggest": {
275
+ "description-suggestions": {
276
+ "phrase": {
277
+ "direct_generator": [
278
+ {
279
+ "field": "title",
280
+ "min_word_length": 1,
281
+ "suggest_mode": "always",
282
+ },
283
+ ],
284
+ "field": "title",
285
+ },
286
+ "text": "powerfull laptop",
287
+ },
288
+ },
289
+ }
290
+ `);
291
+ });
292
+ it('should build phrase suggester with highlighting', () => {
293
+ const result = suggest(matterWithSuggestMappings)
294
+ .phrase('description-suggestions', 'powerfull laptop', {
295
+ field: 'title',
296
+ highlight: {
297
+ pre_tag: '<em>',
298
+ post_tag: '</em>'
299
+ }
300
+ })
301
+ .build();
302
+ expect(result).toMatchInlineSnapshot(`
303
+ {
304
+ "suggest": {
305
+ "description-suggestions": {
306
+ "phrase": {
307
+ "field": "title",
308
+ "highlight": {
309
+ "post_tag": "</em>",
310
+ "pre_tag": "<em>",
311
+ },
312
+ },
313
+ "text": "powerfull laptop",
314
+ },
315
+ },
316
+ }
317
+ `);
318
+ });
319
+ it('should build phrase suggester with collate', () => {
320
+ const result = suggest(matterWithSuggestMappings)
321
+ .phrase('description-suggestions', 'powerfull laptop', {
322
+ field: 'title',
323
+ collate: {
324
+ query: {
325
+ source: '{ "match": { "{{field_name}}": "{{suggestion}}" } }'
326
+ },
327
+ params: { field_name: 'description' },
328
+ prune: true
329
+ }
330
+ })
331
+ .build();
332
+ expect(result).toMatchInlineSnapshot(`
333
+ {
334
+ "suggest": {
335
+ "description-suggestions": {
336
+ "phrase": {
337
+ "collate": {
338
+ "params": {
339
+ "field_name": "description",
340
+ },
341
+ "prune": true,
342
+ "query": {
343
+ "source": "{ "match": { "{{field_name}}": "{{suggestion}}" } }",
344
+ },
345
+ },
346
+ "field": "title",
347
+ },
348
+ "text": "powerfull laptop",
349
+ },
350
+ },
351
+ }
352
+ `);
353
+ });
354
+ it('should build phrase suggester with size option', () => {
355
+ const result = suggest(matterWithSuggestMappings)
356
+ .phrase('description-suggestions', 'powerfull laptop', {
357
+ field: 'title',
358
+ size: 5
359
+ })
360
+ .build();
361
+ expect(result).toMatchInlineSnapshot(`
362
+ {
363
+ "suggest": {
364
+ "description-suggestions": {
365
+ "phrase": {
366
+ "field": "title",
367
+ "size": 5,
368
+ },
369
+ "text": "powerfull laptop",
370
+ },
371
+ },
372
+ }
373
+ `);
374
+ });
375
+ it('should build phrase suggester with gram_size option', () => {
376
+ const result = suggest(matterWithSuggestMappings)
377
+ .phrase('description-suggestions', 'powerfull laptop', {
378
+ field: 'title',
379
+ gram_size: 2
380
+ })
381
+ .build();
382
+ expect(result).toMatchInlineSnapshot(`
383
+ {
384
+ "suggest": {
385
+ "description-suggestions": {
386
+ "phrase": {
387
+ "field": "title",
388
+ "gram_size": 2,
389
+ },
390
+ "text": "powerfull laptop",
391
+ },
392
+ },
393
+ }
394
+ `);
395
+ });
396
+ it('should build phrase suggester with all options', () => {
397
+ const result = suggest(matterWithSuggestMappings)
398
+ .phrase('description-suggestions', 'powerfull laptop', {
399
+ field: 'title',
400
+ size: 3,
401
+ real_word_error_likelihood: 0.95,
402
+ confidence: 2.0,
403
+ max_errors: 0.5,
404
+ gram_size: 3,
405
+ highlight: {
406
+ pre_tag: '<em>',
407
+ post_tag: '</em>'
408
+ }
409
+ })
410
+ .build();
411
+ expect(result).toMatchInlineSnapshot(`
412
+ {
413
+ "suggest": {
414
+ "description-suggestions": {
415
+ "phrase": {
416
+ "confidence": 2,
417
+ "field": "title",
418
+ "gram_size": 3,
419
+ "highlight": {
420
+ "post_tag": "</em>",
421
+ "pre_tag": "<em>",
422
+ },
423
+ "max_errors": 0.5,
424
+ "real_word_error_likelihood": 0.95,
425
+ "size": 3,
426
+ },
427
+ "text": "powerfull laptop",
428
+ },
429
+ },
430
+ }
431
+ `);
432
+ });
433
+ });
434
+ describe('Completion Suggester', () => {
435
+ it('should build basic completion suggester', () => {
436
+ const result = suggest(matterWithSuggestMappings)
437
+ .completion('autocomplete', 'lap', {
438
+ field: 'title_suggest'
439
+ })
440
+ .build();
441
+ expect(result).toMatchInlineSnapshot(`
442
+ {
443
+ "suggest": {
444
+ "autocomplete": {
445
+ "completion": {
446
+ "field": "title_suggest",
447
+ },
448
+ "prefix": "lap",
449
+ },
450
+ },
451
+ }
452
+ `);
453
+ });
454
+ it('should build completion suggester with size', () => {
455
+ const result = suggest(matterWithSuggestMappings)
456
+ .completion('autocomplete', 'lap', {
457
+ field: 'title_suggest',
458
+ size: 10
459
+ })
460
+ .build();
461
+ expect(result).toMatchInlineSnapshot(`
462
+ {
463
+ "suggest": {
464
+ "autocomplete": {
465
+ "completion": {
466
+ "field": "title_suggest",
467
+ "size": 10,
468
+ },
469
+ "prefix": "lap",
470
+ },
471
+ },
472
+ }
473
+ `);
474
+ });
475
+ it('should build completion suggester with skip_duplicates', () => {
476
+ const result = suggest(matterWithSuggestMappings)
477
+ .completion('autocomplete', 'lap', {
478
+ field: 'title_suggest',
479
+ skip_duplicates: true
480
+ })
481
+ .build();
482
+ expect(result).toMatchInlineSnapshot(`
483
+ {
484
+ "suggest": {
485
+ "autocomplete": {
486
+ "completion": {
487
+ "field": "title_suggest",
488
+ "skip_duplicates": true,
489
+ },
490
+ "prefix": "lap",
491
+ },
492
+ },
493
+ }
494
+ `);
495
+ });
496
+ it('should build completion suggester with fuzzy matching', () => {
497
+ const result = suggest(matterWithSuggestMappings)
498
+ .completion('autocomplete', 'lap', {
499
+ field: 'title_suggest',
500
+ fuzzy: {
501
+ fuzziness: 'AUTO',
502
+ transpositions: true,
503
+ min_length: 3,
504
+ prefix_length: 1
505
+ }
506
+ })
507
+ .build();
508
+ expect(result).toMatchInlineSnapshot(`
509
+ {
510
+ "suggest": {
511
+ "autocomplete": {
512
+ "completion": {
513
+ "field": "title_suggest",
514
+ "fuzzy": {
515
+ "fuzziness": "AUTO",
516
+ "min_length": 3,
517
+ "prefix_length": 1,
518
+ "transpositions": true,
519
+ },
520
+ },
521
+ "prefix": "lap",
522
+ },
523
+ },
524
+ }
525
+ `);
526
+ });
527
+ it('should build completion suggester with contexts', () => {
528
+ const result = suggest(matterWithSuggestMappings)
529
+ .completion('autocomplete', 'lap', {
530
+ field: 'title_suggest',
531
+ contexts: {
532
+ category: 'electronics'
533
+ }
534
+ })
535
+ .build();
536
+ expect(result).toMatchInlineSnapshot(`
537
+ {
538
+ "suggest": {
539
+ "autocomplete": {
540
+ "completion": {
541
+ "contexts": {
542
+ "category": "electronics",
543
+ },
544
+ "field": "title_suggest",
545
+ },
546
+ "prefix": "lap",
547
+ },
548
+ },
549
+ }
550
+ `);
551
+ });
552
+ it('should build completion suggester with all options', () => {
553
+ const result = suggest(matterWithSuggestMappings)
554
+ .completion('autocomplete', 'lap', {
555
+ field: 'title_suggest',
556
+ size: 10,
557
+ skip_duplicates: true,
558
+ fuzzy: {
559
+ fuzziness: 2,
560
+ transpositions: true,
561
+ min_length: 3,
562
+ prefix_length: 1,
563
+ unicode_aware: false
564
+ },
565
+ contexts: {
566
+ category: ['electronics', 'computers']
567
+ }
568
+ })
569
+ .build();
570
+ expect(result).toMatchInlineSnapshot(`
571
+ {
572
+ "suggest": {
573
+ "autocomplete": {
574
+ "completion": {
575
+ "contexts": {
576
+ "category": [
577
+ "electronics",
578
+ "computers",
579
+ ],
580
+ },
581
+ "field": "title_suggest",
582
+ "fuzzy": {
583
+ "fuzziness": 2,
584
+ "min_length": 3,
585
+ "prefix_length": 1,
586
+ "transpositions": true,
587
+ "unicode_aware": false,
588
+ },
589
+ "size": 10,
590
+ "skip_duplicates": true,
591
+ },
592
+ "prefix": "lap",
593
+ },
594
+ },
595
+ }
596
+ `);
597
+ });
598
+ });
599
+ describe('Multiple Suggesters', () => {
600
+ it('should combine multiple phrase suggesters', () => {
601
+ const result = suggest(matterWithSuggestMappings)
602
+ .phrase('name-phrase', 'powerfull laptop', { field: 'title' })
603
+ .phrase('desc-phrase', 'garming keybord', { field: 'title' })
604
+ .build();
605
+ expect(result).toMatchInlineSnapshot(`
606
+ {
607
+ "suggest": {
608
+ "desc-phrase": {
609
+ "phrase": {
610
+ "field": "title",
611
+ },
612
+ "text": "garming keybord",
613
+ },
614
+ "name-phrase": {
615
+ "phrase": {
616
+ "field": "title",
617
+ },
618
+ "text": "powerfull laptop",
619
+ },
620
+ },
621
+ }
622
+ `);
623
+ });
624
+ it('should combine multiple completion suggesters', () => {
625
+ const result = suggest(matterWithSuggestMappings)
626
+ .completion('name-auto', 'lap', { field: 'title' })
627
+ .completion('category-auto', 'ele', { field: 'practice_area' })
628
+ .build();
629
+ expect(result).toMatchInlineSnapshot(`
630
+ {
631
+ "suggest": {
632
+ "category-auto": {
633
+ "completion": {
634
+ "field": "practice_area",
635
+ },
636
+ "prefix": "ele",
637
+ },
638
+ "name-auto": {
639
+ "completion": {
640
+ "field": "title",
641
+ },
642
+ "prefix": "lap",
643
+ },
644
+ },
645
+ }
646
+ `);
647
+ });
648
+ it('should combine multiple term suggesters', () => {
649
+ const result = suggest(matterWithSuggestMappings)
650
+ .term('name-suggestions', 'acquistion', { field: 'title' })
651
+ .term('category-suggestions', 'electornics', { field: 'practice_area' })
652
+ .build();
653
+ expect(result).toMatchInlineSnapshot(`
654
+ {
655
+ "suggest": {
656
+ "category-suggestions": {
657
+ "term": {
658
+ "field": "practice_area",
659
+ },
660
+ "text": "electornics",
661
+ },
662
+ "name-suggestions": {
663
+ "term": {
664
+ "field": "title",
665
+ },
666
+ "text": "acquistion",
667
+ },
668
+ },
669
+ }
670
+ `);
671
+ });
672
+ it('should combine different suggester types', () => {
673
+ const result = suggest(matterWithSuggestMappings)
674
+ .term('name-term', 'acquistion', { field: 'title' })
675
+ .phrase('description-phrase', 'powerfull laptop', {
676
+ field: 'title'
677
+ })
678
+ .completion('name-complete', 'lap', { field: 'title_suggest' })
679
+ .build();
680
+ expect(result).toMatchInlineSnapshot(`
681
+ {
682
+ "suggest": {
683
+ "description-phrase": {
684
+ "phrase": {
685
+ "field": "title",
686
+ },
687
+ "text": "powerfull laptop",
688
+ },
689
+ "name-complete": {
690
+ "completion": {
691
+ "field": "title_suggest",
692
+ },
693
+ "prefix": "lap",
694
+ },
695
+ "name-term": {
696
+ "term": {
697
+ "field": "title",
698
+ },
699
+ "text": "acquistion",
700
+ },
701
+ },
702
+ }
703
+ `);
704
+ });
705
+ });
706
+ describe('Suggester with QueryBuilder', () => {
707
+ it('should add term suggester to query', () => {
708
+ const result = query(matterWithSuggestMappings)
709
+ .match('title', 'corporate')
710
+ .suggest((s) => s.term('name-suggestions', 'acquistion', { field: 'title' }))
711
+ .build();
712
+ expect(result).toMatchInlineSnapshot(`
713
+ {
714
+ "query": {
715
+ "match": {
716
+ "title": "corporate",
717
+ },
718
+ },
719
+ "suggest": {
720
+ "name-suggestions": {
721
+ "term": {
722
+ "field": "title",
723
+ },
724
+ "text": "acquistion",
725
+ },
726
+ },
727
+ }
728
+ `);
729
+ });
730
+ it('should add phrase suggester to query', () => {
731
+ const result = query(matterWithSuggestMappings)
732
+ .match('title', 'corporate')
733
+ .suggest((s) => s.phrase('description-suggestions', 'powerfull laptop', {
734
+ field: 'title',
735
+ confidence: 2.0
736
+ }))
737
+ .build();
738
+ expect(result).toMatchInlineSnapshot(`
739
+ {
740
+ "query": {
741
+ "match": {
742
+ "title": "corporate",
743
+ },
744
+ },
745
+ "suggest": {
746
+ "description-suggestions": {
747
+ "phrase": {
748
+ "confidence": 2,
749
+ "field": "title",
750
+ },
751
+ "text": "powerfull laptop",
752
+ },
753
+ },
754
+ }
755
+ `);
756
+ });
757
+ it('should add completion suggester to query', () => {
758
+ const result = query(matterWithSuggestMappings)
759
+ .match('title', 'corporate')
760
+ .suggest((s) => s.completion('autocomplete', 'lap', {
761
+ field: 'title_suggest',
762
+ size: 5
763
+ }))
764
+ .build();
765
+ expect(result).toMatchInlineSnapshot(`
766
+ {
767
+ "query": {
768
+ "match": {
769
+ "title": "corporate",
770
+ },
771
+ },
772
+ "suggest": {
773
+ "autocomplete": {
774
+ "completion": {
775
+ "field": "title_suggest",
776
+ "size": 5,
777
+ },
778
+ "prefix": "lap",
779
+ },
780
+ },
781
+ }
782
+ `);
783
+ });
784
+ it('should add multiple suggesters to query', () => {
785
+ const result = query(matterWithSuggestMappings)
786
+ .match('title', 'corporate')
787
+ .suggest((s) => s.term('name-term', 'acquistion', { field: 'title', size: 3 }).completion('name-complete', 'lap', {
788
+ field: 'title_suggest',
789
+ size: 5
790
+ }))
791
+ .build();
792
+ expect(result).toMatchInlineSnapshot(`
793
+ {
794
+ "query": {
795
+ "match": {
796
+ "title": "corporate",
797
+ },
798
+ },
799
+ "suggest": {
800
+ "name-complete": {
801
+ "completion": {
802
+ "field": "title_suggest",
803
+ "size": 5,
804
+ },
805
+ "prefix": "lap",
806
+ },
807
+ "name-term": {
808
+ "term": {
809
+ "field": "title",
810
+ "size": 3,
811
+ },
812
+ "text": "acquistion",
813
+ },
814
+ },
815
+ }
816
+ `);
817
+ });
818
+ it('should combine query, aggregations, and suggestions', () => {
819
+ const result = query(matterWithSuggestMappings)
820
+ .match('title', 'corporate')
821
+ .aggs((agg) => agg.terms('popular-areas', 'practice_area', { size: 10 }))
822
+ .suggest((s) => s.term('name-suggestions', 'acquistion', { field: 'title', size: 5 }))
823
+ .size(20)
824
+ .build();
825
+ expect(result).toMatchInlineSnapshot(`
826
+ {
827
+ "aggs": {
828
+ "popular-areas": {
829
+ "terms": {
830
+ "field": "practice_area",
831
+ "size": 10,
832
+ },
833
+ },
834
+ },
835
+ "query": {
836
+ "match": {
837
+ "title": "corporate",
838
+ },
839
+ },
840
+ "size": 20,
841
+ "suggest": {
842
+ "name-suggestions": {
843
+ "term": {
844
+ "field": "title",
845
+ "size": 5,
846
+ },
847
+ "text": "acquistion",
848
+ },
849
+ },
850
+ }
851
+ `);
852
+ });
853
+ });
854
+ describe('Suggester method chaining', () => {
855
+ it('should support fluent chaining', () => {
856
+ const result = suggest(matterWithSuggestMappings)
857
+ .term('name-term', 'acquistion', { field: 'title' })
858
+ .phrase('desc-phrase', 'powerfull', { field: 'title' })
859
+ .completion('auto', 'lap', { field: 'title_suggest' })
860
+ .build();
861
+ expect(result.suggest).toHaveProperty('name-term');
862
+ expect(result.suggest).toHaveProperty('desc-phrase');
863
+ expect(result.suggest).toHaveProperty('auto');
864
+ });
865
+ });
866
+ describe('Real-world suggester scenarios', () => {
867
+ it('should build product search with autocomplete', () => {
868
+ const result = query(matterWithSuggestMappings)
869
+ .bool()
870
+ .filter((q) => q.term('practice_area', 'corporate'))
871
+ .suggest((s) => s.completion('product-autocomplete', 'lapt', {
872
+ field: 'title_suggest',
873
+ size: 10,
874
+ fuzzy: {
875
+ fuzziness: 'AUTO',
876
+ prefix_length: 1
877
+ },
878
+ skip_duplicates: true
879
+ }))
880
+ .size(0)
881
+ .build();
882
+ expect(result).toMatchInlineSnapshot(`
883
+ {
884
+ "query": {
885
+ "bool": {
886
+ "filter": [
887
+ {
888
+ "term": {
889
+ "practice_area": "corporate",
890
+ },
891
+ },
892
+ ],
893
+ },
894
+ },
895
+ "size": 0,
896
+ "suggest": {
897
+ "product-autocomplete": {
898
+ "completion": {
899
+ "field": "title_suggest",
900
+ "fuzzy": {
901
+ "fuzziness": "AUTO",
902
+ "prefix_length": 1,
903
+ },
904
+ "size": 10,
905
+ "skip_duplicates": true,
906
+ },
907
+ "prefix": "lapt",
908
+ },
909
+ },
910
+ }
911
+ `);
912
+ });
913
+ it('should build spell-check with term suggester', () => {
914
+ const result = query(matterWithSuggestMappings)
915
+ .match('title', 'acquistion')
916
+ .suggest((s) => s.term('spelling-correction', 'acquistion', {
917
+ field: 'title',
918
+ size: 3,
919
+ suggest_mode: 'popular',
920
+ string_distance: 'levenshtein',
921
+ max_edits: 2,
922
+ prefix_length: 0,
923
+ min_word_length: 3
924
+ }))
925
+ .build();
926
+ expect(result).toMatchInlineSnapshot(`
927
+ {
928
+ "query": {
929
+ "match": {
930
+ "title": "acquistion",
931
+ },
932
+ },
933
+ "suggest": {
934
+ "spelling-correction": {
935
+ "term": {
936
+ "field": "title",
937
+ "max_edits": 2,
938
+ "min_word_length": 3,
939
+ "prefix_length": 0,
940
+ "size": 3,
941
+ "string_distance": "levenshtein",
942
+ "suggest_mode": "popular",
943
+ },
944
+ "text": "acquistion",
945
+ },
946
+ },
947
+ }
948
+ `);
949
+ });
950
+ it('should build phrase correction with highlighting', () => {
951
+ const result = query(matterWithSuggestMappings)
952
+ .match('title', 'powerfull gaming laptop')
953
+ .suggest((s) => s.phrase('phrase-correction', 'powerfull gaming laptop', {
954
+ field: 'title',
955
+ size: 3,
956
+ confidence: 1.5,
957
+ max_errors: 1,
958
+ highlight: {
959
+ pre_tag: '<strong>',
960
+ post_tag: '</strong>'
961
+ },
962
+ direct_generator: [
963
+ {
964
+ field: 'title',
965
+ suggest_mode: 'always',
966
+ max_edits: 2,
967
+ min_word_length: 3
968
+ }
969
+ ]
970
+ }))
971
+ .build();
972
+ expect(result).toMatchInlineSnapshot(`
973
+ {
974
+ "query": {
975
+ "match": {
976
+ "title": "powerfull gaming laptop",
977
+ },
978
+ },
979
+ "suggest": {
980
+ "phrase-correction": {
981
+ "phrase": {
982
+ "confidence": 1.5,
983
+ "direct_generator": [
984
+ {
985
+ "field": "title",
986
+ "max_edits": 2,
987
+ "min_word_length": 3,
988
+ "suggest_mode": "always",
989
+ },
990
+ ],
991
+ "field": "title",
992
+ "highlight": {
993
+ "post_tag": "</strong>",
994
+ "pre_tag": "<strong>",
995
+ },
996
+ "max_errors": 1,
997
+ "size": 3,
998
+ },
999
+ "text": "powerfull gaming laptop",
1000
+ },
1001
+ },
1002
+ }
1003
+ `);
1004
+ });
1005
+ });
1006
+ });