@ocap/indexdb-elasticsearch 1.18.37 → 1.18.38
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/lib/db.js +80 -59
- package/lib/util.js +25 -2
- 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 || 50000;
|
|
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
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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
|
-
|
|
228
|
-
|
|
222
|
+
const condition = getTimeCondition(timeFilter, ['genesisTime', 'renaissanceTime', 'consumedTime']);
|
|
223
|
+
if (condition) {
|
|
224
|
+
conditions.push(condition);
|
|
229
225
|
}
|
|
230
226
|
|
|
231
|
-
|
|
232
|
-
|
|
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
|
-
|
|
304
|
-
|
|
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
|
-
|
|
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
|
-
|
|
426
|
-
|
|
427
|
-
|
|
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({
|
|
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
|
-
|
|
542
|
-
|
|
543
|
-
|
|
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
|
-
|
|
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.
|
|
4
|
+
"version": "1.18.38",
|
|
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": "
|
|
41
|
+
"gitHead": "0ea539a3a0e7a13e7a49daaa4d7e842dcee2192d",
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@arcblock/did": "1.18.
|
|
43
|
+
"@arcblock/did": "1.18.38",
|
|
44
44
|
"@elastic/elasticsearch": "7.13.0",
|
|
45
|
-
"@ocap/indexdb": "1.18.
|
|
46
|
-
"@ocap/util": "1.18.
|
|
45
|
+
"@ocap/indexdb": "1.18.38",
|
|
46
|
+
"@ocap/util": "1.18.38",
|
|
47
47
|
"axios": "^0.25.0",
|
|
48
48
|
"bn.js": "^5.2.1",
|
|
49
49
|
"debug": "^4.3.4",
|