@ocap/indexdb-elasticsearch 1.18.37 → 1.18.39

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 (3) hide show
  1. package/lib/db.js +80 -59
  2. package/lib/util.js +25 -2
  3. package/package.json +5 -5
package/lib/db.js CHANGED
@@ -2,7 +2,6 @@ const axios = require('axios');
2
2
  const { BaseIndexDB } = require('@ocap/indexdb');
3
3
  const { Client: ESClient } = require('@elastic/elasticsearch');
4
4
  const { formatPagination } = require('@ocap/indexdb/lib/util');
5
- const { parseDateTime } = require('@ocap/indexdb/lib/util');
6
5
  const { formatTxAfterRead } = require('@ocap/indexdb/lib/util');
7
6
  const { DEFAULT_TOKEN_DECIMAL } = require('@ocap/util/lib/constant');
8
7
  const { toChecksumAddress } = require('@arcblock/did/lib/type');
@@ -21,12 +20,13 @@ const RollupBlock = require('./table/rollup-block');
21
20
  const RollupValidator = require('./table/rollup-validator');
22
21
 
23
22
  const { name, version } = require('../package.json');
24
- const { formatQueryResult, getAuthHeaders } = require('./util');
23
+ const { formatQueryResult, getAuthHeaders, getTimeCondition } = require('./util');
25
24
 
26
25
  // https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-all-query.html
27
26
  const FALLBACK_QUERY = { match_all: { boost: 1.0 } };
28
27
  const REQUEST_TIMEOUT = 8000;
29
28
  const MAX_REQUEST_FACTORY_ADDRESS_SIZE = 100;
29
+ const TRACK_TOTAL_HITS = +process.env.TRACK_TOTAL_HITS || 10000;
30
30
 
31
31
  class ESIndexDB extends BaseIndexDB {
32
32
  /**
@@ -114,9 +114,6 @@ class ESIndexDB extends BaseIndexDB {
114
114
  const { txs = [] } = txFilter;
115
115
  const { rollups = [] } = rollupFilter;
116
116
  const { stakes = [] } = stakeFilter;
117
- let { startDateTime, endDateTime } = timeFilter;
118
- startDateTime = parseDateTime(startDateTime);
119
- endDateTime = parseDateTime(endDateTime);
120
117
 
121
118
  // OR is spelled should
122
119
  // AND is spelled must
@@ -185,12 +182,9 @@ class ESIndexDB extends BaseIndexDB {
185
182
  conditions.push({ terms: { stakes } });
186
183
  }
187
184
 
188
- if (startDateTime && endDateTime) {
189
- conditions.push({ range: { time: { gt: startDateTime, lte: endDateTime } } });
190
- } else if (startDateTime) {
191
- conditions.push({ range: { time: { gt: startDateTime } } });
192
- } else if (endDateTime) {
193
- conditions.push({ range: { time: { lte: endDateTime } } });
185
+ const condition = getTimeCondition(timeFilter, ['time'], 'time');
186
+ if (condition) {
187
+ conditions.push(condition);
194
188
  }
195
189
 
196
190
  if (validityFilter.validity && validityFilter.validity === 'VALID') {
@@ -206,6 +200,7 @@ class ESIndexDB extends BaseIndexDB {
206
200
  from: pagination.cursor,
207
201
  size: pagination.size,
208
202
  body: {
203
+ track_total_hits: TRACK_TOTAL_HITS,
209
204
  query: conditions.length ? { bool: { must: conditions } } : FALLBACK_QUERY,
210
205
  sort: [{ [pagination.order.field]: { order: pagination.order.type } }],
211
206
  _source: { exclude: ['tx.itxJson.data', 'tx.itxJson.encoded_value'] }, // required to make api fast
@@ -224,24 +219,13 @@ class ESIndexDB extends BaseIndexDB {
224
219
  if (factoryAddress) {
225
220
  conditions.push({ term: { parent: factoryAddress } });
226
221
  }
227
- if (conditions.length === 0) {
228
- return { assets: [], account: null };
222
+ const condition = getTimeCondition(timeFilter, ['genesisTime', 'renaissanceTime', 'consumedTime']);
223
+ if (condition) {
224
+ conditions.push(condition);
229
225
  }
230
226
 
231
- // eslint-disable-next-line prefer-const
232
- let { startDateTime, endDateTime, field = 'renaissanceTime' } = timeFilter;
233
- if (['genesisTime', 'renaissanceTime', 'consumedTime'].includes(field) === false) {
234
- throw new Error('invalid field specified in timeFilter');
235
- }
236
-
237
- startDateTime = parseDateTime(startDateTime);
238
- endDateTime = parseDateTime(endDateTime);
239
- if (startDateTime && endDateTime) {
240
- conditions.push({ range: { [field]: { gt: startDateTime, lte: endDateTime } } });
241
- } else if (startDateTime) {
242
- conditions.push({ range: { [field]: { gt: startDateTime } } });
243
- } else if (endDateTime) {
244
- conditions.push({ range: { [field]: { lte: endDateTime } } });
227
+ if (conditions.length === 0) {
228
+ return { assets: [], account: null };
245
229
  }
246
230
 
247
231
  const pagination = formatPagination({ paging, defaultSortField: 'renaissanceTime' });
@@ -251,6 +235,7 @@ class ESIndexDB extends BaseIndexDB {
251
235
  from: pagination.cursor,
252
236
  size: pagination.size,
253
237
  body: {
238
+ track_total_hits: TRACK_TOTAL_HITS,
254
239
  query: { bool: { must: conditions } },
255
240
  sort: [{ [pagination.order.field]: { order: pagination.order.type } }],
256
241
  },
@@ -262,8 +247,7 @@ class ESIndexDB extends BaseIndexDB {
262
247
  return { assets: items, account, paging: nextPaging };
263
248
  }
264
249
 
265
- async listTopAccounts({ tokenAddress, paging } = {}) {
266
- const filter = { term: { 'tokens.address': tokenAddress } };
250
+ async listTopAccounts({ tokenAddress, paging, timeFilter = {} } = {}) {
267
251
  const pagination = formatPagination({
268
252
  paging,
269
253
  defaultSortField: 'balance',
@@ -272,6 +256,10 @@ class ESIndexDB extends BaseIndexDB {
272
256
 
273
257
  let sort = null;
274
258
  if (pagination.order.field === 'balance') {
259
+ if (!tokenAddress) {
260
+ throw new Error('tokenAddress is required when order.field is balance');
261
+ }
262
+
275
263
  sort = [
276
264
  {
277
265
  'tokens.balance': {
@@ -279,7 +267,7 @@ class ESIndexDB extends BaseIndexDB {
279
267
  order: pagination.order.type,
280
268
  nested: {
281
269
  path: 'tokens',
282
- filter,
270
+ filter: { term: { 'tokens.address': tokenAddress } },
283
271
  },
284
272
  },
285
273
  },
@@ -294,18 +282,32 @@ class ESIndexDB extends BaseIndexDB {
294
282
  ];
295
283
  }
296
284
 
285
+ const conditions = [];
286
+ const condition = getTimeCondition(timeFilter, ['genesisTime', 'renaissanceTime']);
287
+ if (condition) {
288
+ conditions.push(condition);
289
+ }
290
+ if (tokenAddress) {
291
+ conditions.push({
292
+ nested: {
293
+ path: 'tokens',
294
+ query: {
295
+ bool: {
296
+ must: [{ term: { 'tokens.address': tokenAddress } }],
297
+ },
298
+ },
299
+ },
300
+ });
301
+ }
302
+
297
303
  debug('listTopAccounts', { tokenAddress, paging, sort });
298
304
 
299
305
  const result = await this.account.search({
300
306
  from: pagination.cursor,
301
307
  size: pagination.size,
302
308
  body: {
303
- query: {
304
- nested: {
305
- path: 'tokens',
306
- query: { bool: { filter } },
307
- },
308
- },
309
+ track_total_hits: TRACK_TOTAL_HITS,
310
+ query: conditions.length ? { bool: { must: conditions } } : FALLBACK_QUERY,
309
311
  sort,
310
312
  },
311
313
  });
@@ -324,9 +326,20 @@ class ESIndexDB extends BaseIndexDB {
324
326
  return { accounts: items.map((x) => Account.formatAfterRead(x)), paging: nextPaging };
325
327
  }
326
328
 
327
- async listTokens({ issuerAddress, paging } = {}) {
329
+ async listTokens({ issuerAddress, paging, timeFilter = {} } = {}) {
328
330
  debug('listTokens', { issuerAddress, paging });
329
331
 
332
+ const conditions = [];
333
+
334
+ if (issuerAddress) {
335
+ conditions.push({ term: { issuer: issuerAddress } });
336
+ }
337
+
338
+ const condition = getTimeCondition(timeFilter, ['genesisTime', 'renaissanceTime']);
339
+ if (condition) {
340
+ conditions.push(condition);
341
+ }
342
+
330
343
  const pagination = formatPagination({
331
344
  paging,
332
345
  defaultSortField: 'renaissanceTime',
@@ -337,7 +350,8 @@ class ESIndexDB extends BaseIndexDB {
337
350
  from: pagination.cursor,
338
351
  size: pagination.size,
339
352
  body: {
340
- query: issuerAddress ? { bool: { must: [{ term: { issuer: issuerAddress } }] } } : FALLBACK_QUERY,
353
+ track_total_hits: TRACK_TOTAL_HITS,
354
+ query: conditions.length ? { bool: { must: conditions } } : FALLBACK_QUERY,
341
355
  sort: [{ [pagination.order.field]: { order: pagination.order.type } }],
342
356
  },
343
357
  });
@@ -346,7 +360,7 @@ class ESIndexDB extends BaseIndexDB {
346
360
  return { tokens: items.map((x) => Token.formatAfterRead(x)), paging: nextPaging };
347
361
  }
348
362
 
349
- async listFactories({ ownerAddress, addressList, paging } = {}) {
363
+ async listFactories({ ownerAddress, addressList, paging, timeFilter = {} } = {}) {
350
364
  debug('listTokens', { ownerAddress, paging });
351
365
  const pagination = formatPagination({
352
366
  paging,
@@ -359,6 +373,11 @@ class ESIndexDB extends BaseIndexDB {
359
373
  conditions.push({ term: { owner: ownerAddress } });
360
374
  }
361
375
 
376
+ const condition = getTimeCondition(timeFilter, ['genesisTime', 'renaissanceTime']);
377
+ if (condition) {
378
+ conditions.push(condition);
379
+ }
380
+
362
381
  if (Array.isArray(addressList) && addressList.length > 0) {
363
382
  if (addressList.length > MAX_REQUEST_FACTORY_ADDRESS_SIZE) {
364
383
  throw new Error(`The length of 'addressList' cannot exceed the length of ${MAX_REQUEST_FACTORY_ADDRESS_SIZE}`);
@@ -375,6 +394,7 @@ class ESIndexDB extends BaseIndexDB {
375
394
  from: pagination.cursor,
376
395
  size: pagination.size,
377
396
  body: {
397
+ track_total_hits: TRACK_TOTAL_HITS,
378
398
  query: conditions.length > 0 ? { bool: { must: conditions } } : FALLBACK_QUERY,
379
399
  sort: [{ [sortFields[pagination.order.field] || pagination.order.field]: { order: pagination.order.type } }],
380
400
  },
@@ -393,10 +413,6 @@ class ESIndexDB extends BaseIndexDB {
393
413
 
394
414
  const { sender, receiver } = addressFilter;
395
415
  const { assets = [] } = assetFilter;
396
- let { startDateTime, endDateTime, field } = timeFilter;
397
- startDateTime = parseDateTime(startDateTime);
398
- endDateTime = parseDateTime(endDateTime);
399
- field = ['genesisTime', 'renaissanceTime'].includes(field) ? field : 'renaissanceTime';
400
416
 
401
417
  // OR is spelled should
402
418
  // AND is spelled must
@@ -422,12 +438,9 @@ class ESIndexDB extends BaseIndexDB {
422
438
  conditions.push({ terms: { assets } });
423
439
  }
424
440
 
425
- if (startDateTime && endDateTime) {
426
- conditions.push({ range: { [field]: { gt: startDateTime, lte: endDateTime } } });
427
- } else if (startDateTime) {
428
- conditions.push({ range: { [field]: { gt: startDateTime } } });
429
- } else if (endDateTime) {
430
- conditions.push({ range: { [field]: { lte: endDateTime } } });
441
+ const condition = getTimeCondition(timeFilter, ['genesisTime', 'renaissanceTime']);
442
+ if (condition) {
443
+ conditions.push(condition);
431
444
  }
432
445
 
433
446
  debug('listStakes query conditions', conditions);
@@ -436,6 +449,7 @@ class ESIndexDB extends BaseIndexDB {
436
449
  from: pagination.cursor,
437
450
  size: pagination.size,
438
451
  body: {
452
+ track_total_hits: TRACK_TOTAL_HITS,
439
453
  query: conditions.length ? { bool: { must: conditions } } : FALLBACK_QUERY,
440
454
  sort: [{ [pagination.order.field]: { order: pagination.order.type } }],
441
455
  _source: { exclude: [] }, // to make api fast
@@ -446,7 +460,13 @@ class ESIndexDB extends BaseIndexDB {
446
460
  return { stakes: items.map((item) => Stake.formatAfterRead(item)), paging: nextPaging };
447
461
  }
448
462
 
449
- async listRollups({ paging, tokenAddress = '', erc20TokenAddress = '', foreignTokenAddress = '' } = {}) {
463
+ async listRollups({
464
+ paging,
465
+ tokenAddress = '',
466
+ erc20TokenAddress = '',
467
+ foreignTokenAddress = '',
468
+ timeFilter = {},
469
+ } = {}) {
450
470
  const pagination = formatPagination({
451
471
  paging,
452
472
  defaultSortField: 'renaissanceTime',
@@ -457,6 +477,10 @@ class ESIndexDB extends BaseIndexDB {
457
477
  if (tokenAddress) {
458
478
  conditions.push({ term: { tokenAddress } });
459
479
  }
480
+ const condition = getTimeCondition(timeFilter, ['genesisTime', 'renaissanceTime']);
481
+ if (condition) {
482
+ conditions.push(condition);
483
+ }
460
484
  const foreignTokenAddr = foreignTokenAddress || erc20TokenAddress;
461
485
  if (foreignTokenAddr) {
462
486
  conditions.push({
@@ -480,6 +504,7 @@ class ESIndexDB extends BaseIndexDB {
480
504
  from: pagination.cursor,
481
505
  size: pagination.size,
482
506
  body: {
507
+ track_total_hits: TRACK_TOTAL_HITS,
483
508
  query: conditions.length ? { bool: { must: conditions } } : FALLBACK_QUERY,
484
509
  sort: [{ [pagination.order.field]: { order: pagination.order.type } }],
485
510
  },
@@ -503,9 +528,6 @@ class ESIndexDB extends BaseIndexDB {
503
528
 
504
529
  const { txs = [] } = txFilter;
505
530
  const { validators = [] } = validatorFilter;
506
- let { startDateTime, endDateTime, field = 'genesisTime' } = timeFilter; // eslint-disable-line
507
- startDateTime = parseDateTime(startDateTime);
508
- endDateTime = parseDateTime(endDateTime);
509
531
 
510
532
  const conditions = [];
511
533
 
@@ -538,12 +560,9 @@ class ESIndexDB extends BaseIndexDB {
538
560
  conditions.push({ terms: { validators } });
539
561
  }
540
562
 
541
- if (startDateTime && endDateTime) {
542
- conditions.push({ range: { [field]: { gt: startDateTime, lte: endDateTime } } });
543
- } else if (startDateTime) {
544
- conditions.push({ range: { [field]: { gt: startDateTime } } });
545
- } else if (endDateTime) {
546
- conditions.push({ range: { [field]: { lte: endDateTime } } });
563
+ const condition = getTimeCondition(timeFilter, ['genesisTime', 'renaissanceTime']);
564
+ if (condition) {
565
+ conditions.push(condition);
547
566
  }
548
567
 
549
568
  debug('listRollupBlocks query conditions', conditions);
@@ -552,6 +571,7 @@ class ESIndexDB extends BaseIndexDB {
552
571
  from: pagination.cursor,
553
572
  size: pagination.size,
554
573
  body: {
574
+ track_total_hits: TRACK_TOTAL_HITS,
555
575
  query: conditions.length ? { bool: { must: conditions } } : FALLBACK_QUERY,
556
576
  sort: [{ [pagination.order.field]: { order: pagination.order.type } }],
557
577
  },
@@ -580,6 +600,7 @@ class ESIndexDB extends BaseIndexDB {
580
600
  from: pagination.cursor,
581
601
  size: pagination.size,
582
602
  body: {
603
+ track_total_hits: TRACK_TOTAL_HITS,
583
604
  query: conditions.length ? { bool: { must: conditions } } : FALLBACK_QUERY,
584
605
  sort: [{ [pagination.order.field]: { order: pagination.order.type } }],
585
606
  },
package/lib/util.js CHANGED
@@ -1,4 +1,4 @@
1
- const { formatNextPagination } = require('@ocap/indexdb/lib/util');
1
+ const { formatNextPagination, parseDateTime } = require('@ocap/indexdb/lib/util');
2
2
 
3
3
  const getTableName = (prefix, name) => (prefix ? [prefix, name].join('_') : name);
4
4
 
@@ -28,4 +28,27 @@ const getAuthHeaders = (auth) => {
28
28
  return headers;
29
29
  };
30
30
 
31
- module.exports = { getTableName, formatQueryResult, getAuthHeaders };
31
+ const getTimeCondition = (
32
+ filter = {},
33
+ supportedFields = ['genesisTime', 'renaissanceTime'],
34
+ defaultField = 'renaissanceTime'
35
+ ) => {
36
+ let { startDateTime, endDateTime, field } = filter;
37
+ startDateTime = parseDateTime(startDateTime);
38
+ endDateTime = parseDateTime(endDateTime);
39
+ field = supportedFields.includes(field) ? field : defaultField;
40
+
41
+ if (startDateTime && endDateTime) {
42
+ return { range: { [field]: { gt: startDateTime, lte: endDateTime } } };
43
+ }
44
+ if (startDateTime) {
45
+ return { range: { [field]: { gt: startDateTime } } };
46
+ }
47
+ if (endDateTime) {
48
+ return { range: { [field]: { lte: endDateTime } } };
49
+ }
50
+
51
+ return null;
52
+ };
53
+
54
+ module.exports = { getTableName, formatQueryResult, getAuthHeaders, getTimeCondition };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ocap/indexdb-elasticsearch",
3
3
  "description": "OCAP indexdb adapter that uses elasticsearch as backend",
4
- "version": "1.18.37",
4
+ "version": "1.18.39",
5
5
  "author": "wangshijun <shijun@arcblock.io> (https://www.arcblock.io)",
6
6
  "bugs": {
7
7
  "url": "https://github.com/ArcBlock/asset-chain/issues",
@@ -38,12 +38,12 @@
38
38
  "test": "jest --forceExit --detectOpenHandles",
39
39
  "coverage": "npm run test -- --coverage"
40
40
  },
41
- "gitHead": "30215e61b8ff7abb8ccd44981cd5de30bb2b1355",
41
+ "gitHead": "95f7a60030ed923ac83fed697f208a9b8d555f59",
42
42
  "dependencies": {
43
- "@arcblock/did": "1.18.37",
43
+ "@arcblock/did": "1.18.39",
44
44
  "@elastic/elasticsearch": "7.13.0",
45
- "@ocap/indexdb": "1.18.37",
46
- "@ocap/util": "1.18.37",
45
+ "@ocap/indexdb": "1.18.39",
46
+ "@ocap/util": "1.18.39",
47
47
  "axios": "^0.25.0",
48
48
  "bn.js": "^5.2.1",
49
49
  "debug": "^4.3.4",