wok-server 0.5.0 → 0.6.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.en.md +61 -0
- package/README.md +44 -29
- package/dist/cache/cache.js +98 -98
- package/dist/cache/config.js +19 -19
- package/dist/cache/index.js +27 -27
- package/dist/cache/purge-task.js +46 -46
- package/dist/cache/stat.js +47 -47
- package/dist/config/convert.js +36 -36
- package/dist/config/exception.js +14 -14
- package/dist/config/index.js +81 -81
- package/dist/http-client/index.js +136 -136
- package/dist/i18n/ar.js +17 -17
- package/dist/i18n/de.js +17 -17
- package/dist/i18n/en-us.js +17 -17
- package/dist/i18n/es.js +17 -17
- package/dist/i18n/fr.js +17 -17
- package/dist/i18n/i18n.js +231 -231
- package/dist/i18n/index.js +52 -52
- package/dist/i18n/ja.js +17 -17
- package/dist/i18n/ko.js +17 -17
- package/dist/i18n/msg.js +2 -2
- package/dist/i18n/pt.js +17 -17
- package/dist/i18n/ru.js +17 -17
- package/dist/i18n/tag.js +18 -18
- package/dist/i18n/zh-HK.js +17 -17
- package/dist/i18n/zh-TW.js +17 -17
- package/dist/i18n/zh-cn.js +17 -17
- package/dist/index.js +14 -14
- package/dist/lock/index.js +114 -114
- package/dist/log/config.js +35 -35
- package/dist/log/date.js +21 -21
- package/dist/log/file.js +198 -198
- package/dist/log/index.js +135 -135
- package/dist/log/level.js +33 -33
- package/dist/log/log.js +56 -56
- package/dist/log/store.js +19 -19
- package/dist/mongodb/collection.js +2 -2
- package/dist/mongodb/config.js +34 -34
- package/dist/mongodb/doc.js +2 -2
- package/dist/mongodb/exception.js +14 -14
- package/dist/mongodb/index.js +58 -58
- package/dist/mongodb/manager/base.js +563 -563
- package/dist/mongodb/manager/index.js +63 -63
- package/dist/mongodb/manager/tx-strict.js +84 -84
- package/dist/mongodb/manager/tx.js +30 -30
- package/dist/mongodb/migration.js +52 -52
- package/dist/mvc/access-log.js +33 -33
- package/dist/mvc/config.js +27 -27
- package/dist/mvc/exchange.js +113 -113
- package/dist/mvc/handler/index.js +7 -6
- package/dist/mvc/handler/json.js +65 -65
- package/dist/mvc/handler/restful.js +35 -35
- package/dist/mvc/handler/sse.js +65 -0
- package/dist/mvc/handler/upload.js +31 -31
- package/dist/mvc/index.js +50 -50
- package/dist/mvc/interceptor.js +2 -2
- package/dist/mvc/query.js +43 -43
- package/dist/mvc/render/file.js +132 -132
- package/dist/mvc/render/html/html.js +90 -90
- package/dist/mvc/render/html/index.js +18 -18
- package/dist/mvc/render/html/style.js +2 -2
- package/dist/mvc/render/index.js +7 -7
- package/dist/mvc/render/json.js +26 -26
- package/dist/mvc/render/text.js +16 -16
- package/dist/mvc/router.js +2 -2
- package/dist/mvc/server.js +272 -272
- package/dist/mvc/static/header.js +67 -67
- package/dist/mvc/static/index.js +6 -6
- package/dist/mvc/static/mime-type.js +84 -84
- package/dist/mvc/static/server-cache-config.js +66 -66
- package/dist/mvc/static/server-cache.js +133 -133
- package/dist/mvc/static/static-handler.js +372 -372
- package/dist/mysql/config.js +51 -51
- package/dist/mysql/exception.js +14 -14
- package/dist/mysql/index.js +87 -87
- package/dist/mysql/manager/base.js +239 -239
- package/dist/mysql/manager/index.js +107 -107
- package/dist/mysql/manager/ops/count.js +20 -20
- package/dist/mysql/manager/ops/criteria.js +356 -356
- package/dist/mysql/manager/ops/delete.js +65 -65
- package/dist/mysql/manager/ops/exist.js +26 -26
- package/dist/mysql/manager/ops/find.js +169 -169
- package/dist/mysql/manager/ops/index.js +14 -14
- package/dist/mysql/manager/ops/insert.js +106 -106
- package/dist/mysql/manager/ops/modify.js +10 -10
- package/dist/mysql/manager/ops/paginate.js +23 -23
- package/dist/mysql/manager/ops/query.js +9 -9
- package/dist/mysql/manager/ops/update.js +216 -216
- package/dist/mysql/manager/ops/utils.js +24 -24
- package/dist/mysql/manager/tx-strict.js +103 -103
- package/dist/mysql/manager/tx.js +30 -30
- package/dist/mysql/manager/utils.js +56 -56
- package/dist/mysql/migration.js +136 -136
- package/dist/mysql/table-info.js +8 -8
- package/dist/task/daily.js +59 -59
- package/dist/task/fixed-delay.js +38 -38
- package/dist/task/fixed-rate.js +42 -42
- package/dist/task/index.js +9 -9
- package/dist/task/task.js +56 -56
- package/dist/validation/exception.js +36 -36
- package/dist/validation/index.js +40 -40
- package/dist/validation/validator/array.js +34 -34
- package/dist/validation/validator/enum.js +28 -28
- package/dist/validation/validator/index.js +14 -14
- package/dist/validation/validator/length.js +40 -40
- package/dist/validation/validator/max-length.js +35 -35
- package/dist/validation/validator/max.js +29 -29
- package/dist/validation/validator/min-length.js +33 -33
- package/dist/validation/validator/min.js +29 -29
- package/dist/validation/validator/not-blank.js +33 -33
- package/dist/validation/validator/not-null.js +21 -21
- package/dist/validation/validator/plain-obj.js +32 -32
- package/dist/validation/validator/regexp.js +34 -34
- package/documentation/en/cache.md +56 -0
- package/documentation/en/config.md +96 -0
- package/documentation/en/engineering.md +256 -0
- package/documentation/en/http-client.md +32 -0
- package/documentation/en/i18n.md +143 -0
- package/documentation/en/index.md +24 -0
- package/documentation/en/lock.md +51 -0
- package/documentation/en/log.md +109 -0
- package/documentation/en/mongodb.md +256 -0
- package/documentation/en/mvc.md +688 -0
- package/documentation/en/mysql.md +552 -0
- package/documentation/en/task.md +45 -0
- package/documentation/en/test.md +56 -0
- package/documentation/en/validate.md +130 -0
- package/documentation/zh-cn/mvc.md +66 -24
- package/package.json +3 -1
- package/skills/wok-server-api-rules/SKILL.md +350 -0
- package/skills/wok-server-cache/SKILL.md +216 -0
- package/skills/wok-server-config/SKILL.md +200 -0
- package/skills/wok-server-getting-started/SKILL.md +123 -0
- package/skills/wok-server-getting-started/references/engineering.md +169 -0
- package/skills/wok-server-http-client/SKILL.md +164 -0
- package/skills/wok-server-i18n/SKILL.md +214 -0
- package/skills/wok-server-lock/SKILL.md +144 -0
- package/skills/wok-server-log/SKILL.md +218 -0
- package/skills/wok-server-mongodb/SKILL.md +235 -0
- package/skills/wok-server-mvc/SKILL.md +251 -0
- package/skills/wok-server-mvc/references/respond-html.md +157 -0
- package/skills/wok-server-mvc/references/sse.md +121 -0
- package/skills/wok-server-mvc/references/static-files.md +47 -0
- package/skills/wok-server-mvc/references/upload.md +62 -0
- package/skills/wok-server-mvc/references/websocket.md +30 -0
- package/skills/wok-server-mysql/SKILL.md +315 -0
- package/skills/wok-server-mysql/references/multi-datasource.md +76 -0
- package/skills/wok-server-mysql/references/version-control.md +22 -0
- package/skills/wok-server-task/SKILL.md +158 -0
- package/skills/wok-server-validate/SKILL.md +167 -0
- package/src/cache/cache.ts +118 -0
- package/src/cache/config.ts +53 -0
- package/src/cache/index.ts +27 -0
- package/src/cache/purge-task.ts +53 -0
- package/src/cache/stat.ts +47 -0
- package/src/config/convert.ts +27 -0
- package/src/config/exception.ts +8 -0
- package/src/config/index.ts +92 -0
- package/src/http-client/index.ts +202 -0
- package/src/i18n/ar.ts +16 -0
- package/src/i18n/de.ts +16 -0
- package/src/i18n/en-us.ts +16 -0
- package/src/i18n/es.ts +16 -0
- package/src/i18n/fr.ts +16 -0
- package/src/i18n/i18n.ts +230 -0
- package/src/i18n/index.ts +50 -0
- package/src/i18n/ja.ts +16 -0
- package/src/i18n/ko.ts +16 -0
- package/src/i18n/msg.ts +50 -0
- package/src/i18n/pt.ts +16 -0
- package/src/i18n/ru.ts +16 -0
- package/src/i18n/tag.ts +18 -0
- package/src/i18n/zh-HK.ts +16 -0
- package/src/i18n/zh-TW.ts +16 -0
- package/src/i18n/zh-cn.ts +16 -0
- package/src/index.ts +11 -0
- package/src/lock/index.ts +164 -0
- package/src/log/config.ts +71 -0
- package/src/log/date.ts +19 -0
- package/src/log/file.ts +215 -0
- package/src/log/index.ts +136 -0
- package/src/log/level.ts +29 -0
- package/src/log/log.ts +77 -0
- package/src/log/store.ts +31 -0
- package/src/mongodb/collection.ts +25 -0
- package/src/mongodb/config.ts +69 -0
- package/src/mongodb/doc.ts +12 -0
- package/src/mongodb/exception.ts +8 -0
- package/src/mongodb/index.ts +71 -0
- package/src/mongodb/manager/base.ts +674 -0
- package/src/mongodb/manager/index.ts +80 -0
- package/src/mongodb/manager/tx-strict.ts +153 -0
- package/src/mongodb/manager/tx.ts +34 -0
- package/src/mongodb/migration.ts +66 -0
- package/src/mvc/access-log.ts +33 -0
- package/src/mvc/config.ts +70 -0
- package/src/mvc/exchange.ts +126 -0
- package/src/mvc/handler/index.ts +4 -0
- package/src/mvc/handler/json.ts +96 -0
- package/src/mvc/handler/restful.ts +39 -0
- package/src/mvc/handler/sse.ts +90 -0
- package/src/mvc/handler/upload.ts +54 -0
- package/src/mvc/index.ts +48 -0
- package/src/mvc/interceptor.ts +12 -0
- package/src/mvc/query.ts +36 -0
- package/src/mvc/render/file.ts +148 -0
- package/src/mvc/render/html/html.ts +187 -0
- package/src/mvc/render/html/index.ts +16 -0
- package/src/mvc/render/html/style.ts +1201 -0
- package/src/mvc/render/index.ts +4 -0
- package/src/mvc/render/json.ts +24 -0
- package/src/mvc/render/text.ts +14 -0
- package/src/mvc/router.ts +13 -0
- package/src/mvc/server.ts +315 -0
- package/src/mvc/static/header.ts +86 -0
- package/src/mvc/static/index.ts +3 -0
- package/src/mvc/static/mime-type.ts +81 -0
- package/src/mvc/static/server-cache-config.ts +92 -0
- package/src/mvc/static/server-cache.ts +171 -0
- package/src/mvc/static/static-handler.ts +445 -0
- package/src/mysql/config.ts +130 -0
- package/src/mysql/exception.ts +8 -0
- package/src/mysql/index.ts +88 -0
- package/src/mysql/manager/base.ts +285 -0
- package/src/mysql/manager/index.ts +112 -0
- package/src/mysql/manager/ops/count.ts +30 -0
- package/src/mysql/manager/ops/criteria.ts +412 -0
- package/src/mysql/manager/ops/delete.ts +96 -0
- package/src/mysql/manager/ops/exist.ts +41 -0
- package/src/mysql/manager/ops/find.ts +226 -0
- package/src/mysql/manager/ops/index.ts +11 -0
- package/src/mysql/manager/ops/insert.ts +120 -0
- package/src/mysql/manager/ops/modify.ts +14 -0
- package/src/mysql/manager/ops/paginate.ts +60 -0
- package/src/mysql/manager/ops/query.ts +13 -0
- package/src/mysql/manager/ops/update.ts +294 -0
- package/src/mysql/manager/ops/utils.ts +20 -0
- package/src/mysql/manager/tx-strict.ts +138 -0
- package/src/mysql/manager/tx.ts +31 -0
- package/src/mysql/manager/utils.ts +75 -0
- package/src/mysql/migration.ts +149 -0
- package/src/mysql/table-info.ts +41 -0
- package/src/task/daily.ts +70 -0
- package/src/task/fixed-delay.ts +45 -0
- package/src/task/fixed-rate.ts +49 -0
- package/src/task/index.ts +4 -0
- package/src/task/task.ts +70 -0
- package/src/validation/exception.ts +27 -0
- package/src/validation/index.ts +61 -0
- package/src/validation/validator/array.ts +32 -0
- package/src/validation/validator/enum.ts +25 -0
- package/src/validation/validator/index.ts +11 -0
- package/src/validation/validator/length.ts +42 -0
- package/src/validation/validator/max-length.ts +33 -0
- package/src/validation/validator/max.ts +26 -0
- package/src/validation/validator/min-length.ts +31 -0
- package/src/validation/validator/min.ts +26 -0
- package/src/validation/validator/not-blank.ts +31 -0
- package/src/validation/validator/not-null.ts +19 -0
- package/src/validation/validator/plain-obj.ts +30 -0
- package/src/validation/validator/regexp.ts +32 -0
- package/types/cache/cache.d.ts +52 -52
- package/types/cache/config.d.ts +32 -32
- package/types/cache/index.d.ts +2 -2
- package/types/cache/purge-task.d.ts +11 -11
- package/types/cache/stat.d.ts +26 -26
- package/types/config/convert.d.ts +6 -6
- package/types/config/exception.d.ts +7 -7
- package/types/config/index.d.ts +25 -25
- package/types/http-client/index.d.ts +71 -71
- package/types/i18n/ar.d.ts +2 -2
- package/types/i18n/de.d.ts +2 -2
- package/types/i18n/en-us.d.ts +2 -2
- package/types/i18n/es.d.ts +2 -2
- package/types/i18n/fr.d.ts +2 -2
- package/types/i18n/i18n.d.ts +102 -102
- package/types/i18n/index.d.ts +9 -9
- package/types/i18n/ja.d.ts +2 -2
- package/types/i18n/ko.d.ts +2 -2
- package/types/i18n/msg.d.ts +50 -50
- package/types/i18n/pt.d.ts +2 -2
- package/types/i18n/ru.d.ts +2 -2
- package/types/i18n/tag.d.ts +11 -11
- package/types/i18n/zh-HK.d.ts +2 -2
- package/types/i18n/zh-TW.d.ts +2 -2
- package/types/i18n/zh-cn.d.ts +2 -2
- package/types/index.d.ts +11 -11
- package/types/lock/index.d.ts +64 -64
- package/types/log/config.d.ts +35 -35
- package/types/log/date.d.ts +2 -2
- package/types/log/file.d.ts +13 -13
- package/types/log/index.d.ts +53 -53
- package/types/log/level.d.ts +14 -14
- package/types/log/log.d.ts +40 -40
- package/types/log/store.d.ts +19 -19
- package/types/mongodb/collection.d.ts +25 -25
- package/types/mongodb/config.d.ts +45 -45
- package/types/mongodb/doc.d.ts +11 -11
- package/types/mongodb/exception.d.ts +7 -7
- package/types/mongodb/index.d.ts +29 -29
- package/types/mongodb/manager/base.d.ts +188 -188
- package/types/mongodb/manager/index.d.ts +38 -38
- package/types/mongodb/manager/tx-strict.d.ts +41 -41
- package/types/mongodb/manager/tx.d.ts +21 -21
- package/types/mongodb/migration.d.ts +12 -12
- package/types/mvc/access-log.d.ts +7 -7
- package/types/mvc/config.d.ts +42 -42
- package/types/mvc/exchange.d.ts +72 -72
- package/types/mvc/handler/index.d.ts +4 -3
- package/types/mvc/handler/json.d.ts +44 -44
- package/types/mvc/handler/restful.d.ts +11 -11
- package/types/mvc/handler/sse.d.ts +34 -0
- package/types/mvc/handler/upload.d.ts +36 -36
- package/types/mvc/index.d.ts +22 -22
- package/types/mvc/interceptor.d.ts +11 -11
- package/types/mvc/query.d.ts +13 -13
- package/types/mvc/render/file.d.ts +10 -10
- package/types/mvc/render/html/html.d.ts +98 -98
- package/types/mvc/render/html/index.d.ts +11 -11
- package/types/mvc/render/html/style.d.ts +1201 -1201
- package/types/mvc/render/index.d.ts +4 -4
- package/types/mvc/render/json.d.ts +17 -17
- package/types/mvc/render/text.d.ts +10 -10
- package/types/mvc/router.d.ts +11 -11
- package/types/mvc/server.d.ts +90 -90
- package/types/mvc/static/header.d.ts +27 -27
- package/types/mvc/static/index.d.ts +3 -3
- package/types/mvc/static/mime-type.d.ts +2 -2
- package/types/mvc/static/server-cache-config.d.ts +30 -30
- package/types/mvc/static/server-cache.d.ts +76 -76
- package/types/mvc/static/static-handler.d.ts +77 -77
- package/types/mysql/config.d.ts +90 -90
- package/types/mysql/exception.d.ts +7 -7
- package/types/mysql/index.d.ts +16 -16
- package/types/mysql/manager/base.d.ts +165 -165
- package/types/mysql/manager/index.d.ts +36 -36
- package/types/mysql/manager/ops/count.d.ts +13 -13
- package/types/mysql/manager/ops/criteria.d.ts +134 -134
- package/types/mysql/manager/ops/delete.d.ts +46 -46
- package/types/mysql/manager/ops/exist.d.ts +6 -6
- package/types/mysql/manager/ops/find.d.ts +86 -86
- package/types/mysql/manager/ops/index.d.ts +10 -10
- package/types/mysql/manager/ops/insert.d.ts +18 -18
- package/types/mysql/manager/ops/modify.d.ts +3 -3
- package/types/mysql/manager/ops/paginate.d.ts +36 -36
- package/types/mysql/manager/ops/query.d.ts +3 -3
- package/types/mysql/manager/ops/update.d.ts +76 -76
- package/types/mysql/manager/ops/utils.d.ts +5 -5
- package/types/mysql/manager/tx-strict.d.ts +36 -36
- package/types/mysql/manager/tx.d.ts +15 -15
- package/types/mysql/manager/utils.d.ts +17 -17
- package/types/mysql/migration.d.ts +8 -8
- package/types/mysql/table-info.d.ts +36 -36
- package/types/task/daily.d.ts +16 -16
- package/types/task/fixed-delay.d.ts +9 -9
- package/types/task/fixed-rate.d.ts +9 -9
- package/types/task/index.d.ts +4 -4
- package/types/task/task.d.ts +34 -34
- package/types/validation/exception.d.ts +38 -38
- package/types/validation/index.d.ts +32 -32
- package/types/validation/validator/array.d.ts +5 -5
- package/types/validation/validator/enum.d.ts +8 -8
- package/types/validation/validator/index.d.ts +11 -11
- package/types/validation/validator/length.d.ts +10 -10
- package/types/validation/validator/max-length.d.ts +8 -8
- package/types/validation/validator/max.d.ts +7 -7
- package/types/validation/validator/min-length.d.ts +6 -6
- package/types/validation/validator/min.d.ts +7 -7
- package/types/validation/validator/not-blank.d.ts +7 -7
- package/types/validation/validator/not-null.d.ts +6 -6
- package/types/validation/validator/plain-obj.d.ts +7 -7
- package/types/validation/validator/regexp.d.ts +8 -8
|
@@ -0,0 +1,674 @@
|
|
|
1
|
+
import { ClientSession, Db, Document, Filter, SortDirection, UpdateFilter } from 'mongodb'
|
|
2
|
+
import { getLogger } from '../../log'
|
|
3
|
+
import { min, notNull, validate } from '../../validation'
|
|
4
|
+
import { MongoCollection } from '../collection'
|
|
5
|
+
import { MongoDBConfig } from '../config'
|
|
6
|
+
import { MongoDocId, MongoDocWithId } from '../doc'
|
|
7
|
+
import { MongoDBException } from '../exception'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* mysql 分页查询结果
|
|
11
|
+
*/
|
|
12
|
+
export interface MongoPage<T> {
|
|
13
|
+
total: number
|
|
14
|
+
list: T[]
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* mongodb 管理器基类,提供基本的操作功能.
|
|
19
|
+
*/
|
|
20
|
+
export abstract class BaseMongoManager {
|
|
21
|
+
/**
|
|
22
|
+
* mongodb 管理器构建
|
|
23
|
+
* @param db 库
|
|
24
|
+
* @param session 要绑定的会话,用于事务
|
|
25
|
+
*/
|
|
26
|
+
constructor(
|
|
27
|
+
protected config: MongoDBConfig,
|
|
28
|
+
protected readonly db: Db,
|
|
29
|
+
private session?: ClientSession
|
|
30
|
+
) {}
|
|
31
|
+
|
|
32
|
+
getCollection<T extends Document>(collInfo: MongoCollection<T>) {
|
|
33
|
+
return this.db.collection<T>(collInfo.collectionName)
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 查询计时
|
|
37
|
+
* @param opts
|
|
38
|
+
*/
|
|
39
|
+
protected async timingQuery<T, D extends { op: string; coll: string }>(opts: {
|
|
40
|
+
// 查询处理逻辑
|
|
41
|
+
query: () => Promise<T>
|
|
42
|
+
// 信息描述,当查询较慢时打印到日志中
|
|
43
|
+
desc: () => D
|
|
44
|
+
}): Promise<T> {
|
|
45
|
+
const start = new Date().getTime()
|
|
46
|
+
try {
|
|
47
|
+
return await opts.query()
|
|
48
|
+
} finally {
|
|
49
|
+
if (this.config.slowQueryWarn) {
|
|
50
|
+
const cost = new Date().getTime() - start
|
|
51
|
+
if (cost > this.config.slowQueryMs) {
|
|
52
|
+
getLogger().warn(`[mongodb slow query] ${cost}ms ${JSON.stringify(opts.desc())}`)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async findById<T extends Document>(
|
|
59
|
+
coll: MongoCollection<T>,
|
|
60
|
+
id: MongoDocId
|
|
61
|
+
): Promise<MongoDocWithId<T> | null> {
|
|
62
|
+
return this.timingQuery({
|
|
63
|
+
query: async () => {
|
|
64
|
+
const res = await this.getCollection(coll).findOne({ _id: id } as Filter<T>, {
|
|
65
|
+
limit: 1,
|
|
66
|
+
session: this.session
|
|
67
|
+
})
|
|
68
|
+
return res as MongoDocWithId<T> | null
|
|
69
|
+
},
|
|
70
|
+
desc: () => ({
|
|
71
|
+
op: 'findById',
|
|
72
|
+
coll: coll.collectionName,
|
|
73
|
+
id
|
|
74
|
+
})
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* 根据id列表查询
|
|
80
|
+
* @param coll
|
|
81
|
+
* @param ids
|
|
82
|
+
* @returns
|
|
83
|
+
*/
|
|
84
|
+
findByIdIn<T extends Document>(
|
|
85
|
+
coll: MongoCollection<T>,
|
|
86
|
+
ids: MongoDocId[]
|
|
87
|
+
): Promise<MongoDocWithId<T>[]> {
|
|
88
|
+
return this.timingQuery({
|
|
89
|
+
query: async () => {
|
|
90
|
+
const res = this.getCollection(coll).find<MongoDocWithId<T>>(
|
|
91
|
+
{ _id: { $in: ids } } as Filter<T>,
|
|
92
|
+
{ session: this.session }
|
|
93
|
+
)
|
|
94
|
+
return res.toArray()
|
|
95
|
+
},
|
|
96
|
+
desc() {
|
|
97
|
+
return {
|
|
98
|
+
op: 'findByIdIn',
|
|
99
|
+
coll: coll.collectionName,
|
|
100
|
+
ids
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
})
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* 根据id判定是否存在
|
|
108
|
+
* @param coll
|
|
109
|
+
* @param id
|
|
110
|
+
*/
|
|
111
|
+
async existsById<T extends Document>(coll: MongoCollection<T>, id: MongoDocId): Promise<boolean> {
|
|
112
|
+
const res = await this.findById(coll, id)
|
|
113
|
+
return !!res
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* 按指定的条件来判定是否存在记录
|
|
117
|
+
* @param coll
|
|
118
|
+
* @param filter
|
|
119
|
+
*/
|
|
120
|
+
async existsBy<T extends Document>(
|
|
121
|
+
coll: MongoCollection<T>,
|
|
122
|
+
filter: Filter<MongoDocWithId<T>>
|
|
123
|
+
): Promise<boolean> {
|
|
124
|
+
return this.timingQuery({
|
|
125
|
+
query: async () => {
|
|
126
|
+
const res = await this.getCollection(coll).findOne(filter as Filter<T>, {
|
|
127
|
+
limit: 1,
|
|
128
|
+
session: this.session
|
|
129
|
+
})
|
|
130
|
+
return !!res
|
|
131
|
+
},
|
|
132
|
+
desc() {
|
|
133
|
+
return {
|
|
134
|
+
op: 'existsBy',
|
|
135
|
+
coll: coll.collectionName,
|
|
136
|
+
filter
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
})
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* 按id进行删除
|
|
143
|
+
* @param coll
|
|
144
|
+
* @param id
|
|
145
|
+
* @returns
|
|
146
|
+
*/
|
|
147
|
+
async deleteById<T extends Document>(coll: MongoCollection<T>, id: MongoDocId): Promise<boolean> {
|
|
148
|
+
return this.timingQuery({
|
|
149
|
+
query: async () => {
|
|
150
|
+
const res = await this.getCollection(coll).deleteOne({ _id: id } as Filter<T>, {
|
|
151
|
+
session: this.session
|
|
152
|
+
})
|
|
153
|
+
return res.deletedCount === 1
|
|
154
|
+
},
|
|
155
|
+
desc() {
|
|
156
|
+
return {
|
|
157
|
+
op: 'deleteById',
|
|
158
|
+
coll: coll.collectionName,
|
|
159
|
+
id
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
})
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* 仅删除一条记录
|
|
167
|
+
* @param coll
|
|
168
|
+
* @param filter
|
|
169
|
+
* @returns
|
|
170
|
+
*/
|
|
171
|
+
async deleteOne<T extends Document>(
|
|
172
|
+
coll: MongoCollection<T>,
|
|
173
|
+
filter: Partial<T>
|
|
174
|
+
): Promise<boolean> {
|
|
175
|
+
if (!Object.keys(filter).length) {
|
|
176
|
+
throw new MongoDBException('filter cannot be empty !')
|
|
177
|
+
}
|
|
178
|
+
return this.timingQuery({
|
|
179
|
+
query: async () => {
|
|
180
|
+
const res = await this.getCollection(coll).deleteOne(filter as Filter<T>, {
|
|
181
|
+
session: this.session
|
|
182
|
+
})
|
|
183
|
+
return res.deletedCount === 1
|
|
184
|
+
},
|
|
185
|
+
desc() {
|
|
186
|
+
return {
|
|
187
|
+
op: 'deleteMany',
|
|
188
|
+
coll: coll.collectionName,
|
|
189
|
+
filter
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
})
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* 按条件删除数据,返回删除的记录行数.
|
|
197
|
+
* 务必谨慎使用,大批量删除容易带来性能问题,造成线上事故.
|
|
198
|
+
* @param coll
|
|
199
|
+
* @param filter
|
|
200
|
+
* @returns 被删除记录的数量
|
|
201
|
+
*/
|
|
202
|
+
async deleteMany<T extends Document>(
|
|
203
|
+
coll: MongoCollection<T>,
|
|
204
|
+
filter: Filter<MongoDocWithId<T>>
|
|
205
|
+
): Promise<number> {
|
|
206
|
+
if (!Object.keys(filter).length) {
|
|
207
|
+
throw new MongoDBException('filter cannot be empty !')
|
|
208
|
+
}
|
|
209
|
+
return this.timingQuery({
|
|
210
|
+
query: async () => {
|
|
211
|
+
const res = await this.getCollection(coll).deleteMany(filter as Filter<T>, {
|
|
212
|
+
session: this.session
|
|
213
|
+
})
|
|
214
|
+
return res.deletedCount
|
|
215
|
+
},
|
|
216
|
+
desc() {
|
|
217
|
+
return {
|
|
218
|
+
op: 'deleteMany',
|
|
219
|
+
coll: coll.collectionName,
|
|
220
|
+
filter
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
})
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* 查询集合中所有记录.谨慎使用!
|
|
228
|
+
* @param coll
|
|
229
|
+
* @returns
|
|
230
|
+
*/
|
|
231
|
+
async findAll<T extends Document>(coll: MongoCollection<T>): Promise<MongoDocWithId<T>[]> {
|
|
232
|
+
return this.timingQuery({
|
|
233
|
+
query: async () => {
|
|
234
|
+
const arr = await this.getCollection(coll).find({}, { session: this.session }).toArray()
|
|
235
|
+
return arr as MongoDocWithId<T>[]
|
|
236
|
+
},
|
|
237
|
+
desc() {
|
|
238
|
+
return {
|
|
239
|
+
op: 'findAll',
|
|
240
|
+
coll: coll.collectionName
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
})
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* 根据给定的条件查找第一条符合条件的记录
|
|
247
|
+
* @param coll
|
|
248
|
+
* @param filter
|
|
249
|
+
* @returns
|
|
250
|
+
*/
|
|
251
|
+
async findFirst<T extends Document>(
|
|
252
|
+
coll: MongoCollection<T>,
|
|
253
|
+
filter: Filter<MongoDocWithId<T>>
|
|
254
|
+
): Promise<MongoDocWithId<T> | null> {
|
|
255
|
+
return this.timingQuery({
|
|
256
|
+
query: async () => {
|
|
257
|
+
const res = await this.getCollection(coll).findOne(filter as Filter<T>, {
|
|
258
|
+
limit: 1,
|
|
259
|
+
session: this.session
|
|
260
|
+
})
|
|
261
|
+
return res as MongoDocWithId<T> | null
|
|
262
|
+
},
|
|
263
|
+
desc() {
|
|
264
|
+
return {
|
|
265
|
+
op: 'findFirst',
|
|
266
|
+
coll: coll.collectionName,
|
|
267
|
+
filter
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
})
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* 插入新记录
|
|
274
|
+
* @param coll
|
|
275
|
+
* @param data
|
|
276
|
+
* @returns
|
|
277
|
+
*/
|
|
278
|
+
async insert<T extends Document>(
|
|
279
|
+
coll: MongoCollection<T>,
|
|
280
|
+
data: T & { _id?: MongoDocId }
|
|
281
|
+
): Promise<MongoDocWithId<T>> {
|
|
282
|
+
return this.timingQuery({
|
|
283
|
+
query: async () => {
|
|
284
|
+
// 创建时间和更新时间
|
|
285
|
+
if (coll.createdDate) {
|
|
286
|
+
const createdData = coll.createdDate.type === 'date' ? new Date() : new Date().getTime()
|
|
287
|
+
data[coll.createdDate.field] = createdData as any
|
|
288
|
+
}
|
|
289
|
+
if (coll.updatedDate) {
|
|
290
|
+
const updatedDate = coll.updatedDate.type === 'date' ? new Date() : new Date().getTime()
|
|
291
|
+
data[coll.updatedDate.field] = updatedDate as any
|
|
292
|
+
}
|
|
293
|
+
const collection = this.getCollection(coll)
|
|
294
|
+
const res = await collection.insertOne(data as any, { session: this.session })
|
|
295
|
+
if (data._id) {
|
|
296
|
+
return data as any
|
|
297
|
+
}
|
|
298
|
+
data._id = res.insertedId
|
|
299
|
+
return data as any
|
|
300
|
+
},
|
|
301
|
+
desc() {
|
|
302
|
+
return {
|
|
303
|
+
op: 'insert',
|
|
304
|
+
coll: coll.collectionName,
|
|
305
|
+
data
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
})
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* 插入多条,批量插入.
|
|
312
|
+
* @param coll
|
|
313
|
+
* @param list
|
|
314
|
+
*/
|
|
315
|
+
async insertMany<T extends Document>(
|
|
316
|
+
coll: MongoCollection<T>,
|
|
317
|
+
list: Array<T & { _id?: MongoDocId }>
|
|
318
|
+
): Promise<MongoDocWithId<T>[]> {
|
|
319
|
+
return this.timingQuery({
|
|
320
|
+
query: async () => {
|
|
321
|
+
const docList = list.map(data => {
|
|
322
|
+
// 创建时间和更新时间
|
|
323
|
+
if (coll.createdDate) {
|
|
324
|
+
const createdData = coll.createdDate.type === 'date' ? new Date() : new Date().getTime()
|
|
325
|
+
data[coll.createdDate.field] = createdData as any
|
|
326
|
+
}
|
|
327
|
+
if (coll.updatedDate) {
|
|
328
|
+
const updatedDate = coll.updatedDate.type === 'date' ? new Date() : new Date().getTime()
|
|
329
|
+
data[coll.updatedDate.field] = updatedDate as any
|
|
330
|
+
}
|
|
331
|
+
return data
|
|
332
|
+
})
|
|
333
|
+
|
|
334
|
+
const collection = this.getCollection(coll)
|
|
335
|
+
const res = await collection.insertMany(docList as any, { session: this.session })
|
|
336
|
+
docList.forEach((doc, idx) => {
|
|
337
|
+
if (doc._id) {
|
|
338
|
+
return
|
|
339
|
+
}
|
|
340
|
+
if (res.insertedIds[idx]) {
|
|
341
|
+
doc._id = res.insertedIds[idx]
|
|
342
|
+
}
|
|
343
|
+
})
|
|
344
|
+
return docList as any
|
|
345
|
+
},
|
|
346
|
+
desc() {
|
|
347
|
+
return {
|
|
348
|
+
op: 'insertMany',
|
|
349
|
+
coll: coll.collectionName,
|
|
350
|
+
list
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
})
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* 更新,更新完整的文档内容。
|
|
357
|
+
* @param coll 集合信息
|
|
358
|
+
* @param data 要更新的数据,必须包含 _id 字段,支持 mongo 更新语法 $inc 等
|
|
359
|
+
* @returns 返回最新的数据
|
|
360
|
+
* @throws MongoDBException 当无法完成更新时抛出
|
|
361
|
+
*/
|
|
362
|
+
async update<T extends Document>(
|
|
363
|
+
coll: MongoCollection<T>,
|
|
364
|
+
data: MongoDocWithId<T>
|
|
365
|
+
): Promise<MongoDocWithId<T>> {
|
|
366
|
+
return this.timingQuery({
|
|
367
|
+
query: async () => {
|
|
368
|
+
const id = data._id
|
|
369
|
+
if (!id) {
|
|
370
|
+
throw new MongoDBException(
|
|
371
|
+
`Cannot update a document without an id,collection name:${coll.collectionName}`
|
|
372
|
+
)
|
|
373
|
+
}
|
|
374
|
+
delete (data as any)._id
|
|
375
|
+
let createData: any = undefined
|
|
376
|
+
// 保护创建时间不被更新
|
|
377
|
+
if (coll.createdDate && data[coll.createdDate.field]) {
|
|
378
|
+
createData = data[coll.createdDate.field]
|
|
379
|
+
delete data[coll.createdDate.field]
|
|
380
|
+
}
|
|
381
|
+
// 更新时间
|
|
382
|
+
if (coll.updatedDate) {
|
|
383
|
+
const updatedDate = coll.updatedDate.type === 'date' ? new Date() : new Date().getTime()
|
|
384
|
+
data[coll.updatedDate.field] = updatedDate as any
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
const res = await this.getCollection(coll).updateOne(
|
|
388
|
+
{ _id: id } as Filter<T>,
|
|
389
|
+
{ $set: data },
|
|
390
|
+
{
|
|
391
|
+
session: this.session
|
|
392
|
+
}
|
|
393
|
+
)
|
|
394
|
+
if (res.modifiedCount !== 1) {
|
|
395
|
+
throw new MongoDBException(
|
|
396
|
+
`Failed to update record, possibly due to non-existent record,collection:${coll.collectionName},id:${id}`
|
|
397
|
+
)
|
|
398
|
+
}
|
|
399
|
+
data._id = id
|
|
400
|
+
if (coll.createdDate && createData) {
|
|
401
|
+
data[coll.createdDate.field] = createData
|
|
402
|
+
}
|
|
403
|
+
return data
|
|
404
|
+
},
|
|
405
|
+
desc() {
|
|
406
|
+
return {
|
|
407
|
+
op: 'update',
|
|
408
|
+
coll: coll.collectionName,
|
|
409
|
+
data
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
})
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* 仅更新一条记录
|
|
416
|
+
* @param coll
|
|
417
|
+
* @param filter
|
|
418
|
+
* @param updater
|
|
419
|
+
*/
|
|
420
|
+
async updateOne<T extends Document>(
|
|
421
|
+
coll: MongoCollection<T>,
|
|
422
|
+
filter: Partial<T>,
|
|
423
|
+
updater: UpdateFilter<T>
|
|
424
|
+
) {
|
|
425
|
+
if (!Object.keys(filter).length) {
|
|
426
|
+
throw new MongoDBException('filter cannot be empty !')
|
|
427
|
+
}
|
|
428
|
+
if (!Object.keys(updater).length) {
|
|
429
|
+
throw new MongoDBException('updater cannot be empty !')
|
|
430
|
+
}
|
|
431
|
+
return this.timingQuery({
|
|
432
|
+
query: async () => {
|
|
433
|
+
// 更新时间处理
|
|
434
|
+
if (coll.updatedDate) {
|
|
435
|
+
const updatedDate: any =
|
|
436
|
+
coll.updatedDate.type === 'date' ? new Date() : new Date().getTime()
|
|
437
|
+
if (updater.$set) {
|
|
438
|
+
updater.$set[coll.updatedDate.field] = updatedDate
|
|
439
|
+
} else {
|
|
440
|
+
updater.$set = { [coll.updatedDate.field]: updatedDate } as any
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
const res = await this.getCollection(coll).updateOne(filter as Filter<T>, updater, {
|
|
444
|
+
session: this.session
|
|
445
|
+
})
|
|
446
|
+
return res.modifiedCount === 1
|
|
447
|
+
},
|
|
448
|
+
desc() {
|
|
449
|
+
return {
|
|
450
|
+
op: 'updateOne',
|
|
451
|
+
coll: coll.collectionName,
|
|
452
|
+
filter,
|
|
453
|
+
updator: updater
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
})
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* 局部更新,仅更新部分字段,可对字段做递增或数组元组的处理。
|
|
460
|
+
* @param coll 集合信息
|
|
461
|
+
* @param id id
|
|
462
|
+
* @param updater 更新内容
|
|
463
|
+
* @returns 更新是否成功
|
|
464
|
+
*/
|
|
465
|
+
async partialUpdate<T extends Document>(
|
|
466
|
+
coll: MongoCollection<T>,
|
|
467
|
+
id: MongoDocId,
|
|
468
|
+
updater: UpdateFilter<T>
|
|
469
|
+
): Promise<boolean> {
|
|
470
|
+
if (!Object.keys(updater).length) {
|
|
471
|
+
throw new MongoDBException('updater cannot be empty !')
|
|
472
|
+
}
|
|
473
|
+
return this.timingQuery({
|
|
474
|
+
query: async () => {
|
|
475
|
+
// 更新时间处理
|
|
476
|
+
if (coll.updatedDate) {
|
|
477
|
+
const updatedDate: any =
|
|
478
|
+
coll.updatedDate.type === 'date' ? new Date() : new Date().getTime()
|
|
479
|
+
if (updater.$set) {
|
|
480
|
+
updater.$set[coll.updatedDate.field] = updatedDate
|
|
481
|
+
} else {
|
|
482
|
+
updater.$set = { [coll.updatedDate.field]: updatedDate } as any
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
const res = await this.getCollection(coll).updateOne({ _id: id as any }, updater, {
|
|
486
|
+
session: this.session
|
|
487
|
+
})
|
|
488
|
+
return res.modifiedCount === 1
|
|
489
|
+
},
|
|
490
|
+
desc() {
|
|
491
|
+
return {
|
|
492
|
+
op: 'partialUpdate',
|
|
493
|
+
coll: coll.collectionName,
|
|
494
|
+
id,
|
|
495
|
+
updator: updater
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
})
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* 根据条件更新多条记录,和 partialUpdate 区别是可以根据过滤条件来处理多条记录。
|
|
503
|
+
* @param coll 集合
|
|
504
|
+
* @param filter 过滤规则
|
|
505
|
+
* @param updater 更新内容
|
|
506
|
+
* @returns 此次更新的记录数
|
|
507
|
+
*/
|
|
508
|
+
async updateMany<T extends Document>(
|
|
509
|
+
coll: MongoCollection<T>,
|
|
510
|
+
filter: Filter<MongoDocWithId<T>>,
|
|
511
|
+
updater: UpdateFilter<T>
|
|
512
|
+
): Promise<number> {
|
|
513
|
+
if (!Object.keys(filter).length) {
|
|
514
|
+
throw new MongoDBException('filter cannot be empty !')
|
|
515
|
+
}
|
|
516
|
+
if (!Object.keys(updater).length) {
|
|
517
|
+
throw new MongoDBException('updater cannot be empty !')
|
|
518
|
+
}
|
|
519
|
+
return this.timingQuery({
|
|
520
|
+
query: async () => {
|
|
521
|
+
// 更新时间处理
|
|
522
|
+
if (coll.updatedDate) {
|
|
523
|
+
const updatedDate: any =
|
|
524
|
+
coll.updatedDate.type === 'date' ? new Date() : new Date().getTime()
|
|
525
|
+
if (updater.$set) {
|
|
526
|
+
updater.$set[coll.updatedDate.field] = updatedDate
|
|
527
|
+
} else {
|
|
528
|
+
updater.$set = { [coll.updatedDate.field]: updatedDate } as any
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
const res = await this.getCollection(coll).updateMany(filter as Filter<T>, updater, {
|
|
532
|
+
session: this.session
|
|
533
|
+
})
|
|
534
|
+
return res.modifiedCount
|
|
535
|
+
},
|
|
536
|
+
desc() {
|
|
537
|
+
return {
|
|
538
|
+
op: 'updateMany',
|
|
539
|
+
coll: coll.collectionName,
|
|
540
|
+
filter,
|
|
541
|
+
updator: updater
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
})
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
/**
|
|
548
|
+
* 条件查询
|
|
549
|
+
* @param coll 集合信息
|
|
550
|
+
* @param filter 过滤条件
|
|
551
|
+
* @param opts 额外的选项
|
|
552
|
+
* @returns
|
|
553
|
+
*/
|
|
554
|
+
async find<T extends Document>(
|
|
555
|
+
coll: MongoCollection<T>,
|
|
556
|
+
filter: Filter<MongoDocWithId<T>>,
|
|
557
|
+
opts?: {
|
|
558
|
+
/**
|
|
559
|
+
* 偏移,需要 limit 有值才可以
|
|
560
|
+
*/
|
|
561
|
+
offset?: number
|
|
562
|
+
/**
|
|
563
|
+
* 限制返回的数量
|
|
564
|
+
*/
|
|
565
|
+
limit?: number
|
|
566
|
+
/**
|
|
567
|
+
* 排序规则,按先后顺序放入,每个规则是一个元组,第一个元素是字段名称,第二个元素是顺序
|
|
568
|
+
*/
|
|
569
|
+
orderBy?: Array<[keyof MongoDocWithId<T>, 'asc' | 'desc']>
|
|
570
|
+
}
|
|
571
|
+
): Promise<MongoDocWithId<T>[]> {
|
|
572
|
+
return this.timingQuery({
|
|
573
|
+
query: async () => {
|
|
574
|
+
const arr = await this.getCollection(coll)
|
|
575
|
+
.find(filter as Filter<T>, {
|
|
576
|
+
limit: opts && opts.limit && opts.limit > 0 ? opts.limit : undefined,
|
|
577
|
+
skip:
|
|
578
|
+
opts && opts.limit && opts.limit > 0 && opts.offset && opts.offset > 0
|
|
579
|
+
? opts.offset
|
|
580
|
+
: undefined,
|
|
581
|
+
sort: opts && opts.orderBy ? (opts.orderBy as [string, SortDirection][]) : undefined,
|
|
582
|
+
session: this.session
|
|
583
|
+
})
|
|
584
|
+
.toArray()
|
|
585
|
+
return arr as MongoDocWithId<T>[]
|
|
586
|
+
},
|
|
587
|
+
desc() {
|
|
588
|
+
return {
|
|
589
|
+
op: 'find',
|
|
590
|
+
coll: coll.collectionName,
|
|
591
|
+
filter,
|
|
592
|
+
opts
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
})
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* 查询符合条件的文档数量。请谨慎使用,count 是不能从索引直接读取的,只能实时计数,使用不当容易造成性能问题,引发线上事故。
|
|
599
|
+
* @param coll
|
|
600
|
+
* @param filter
|
|
601
|
+
* @returns
|
|
602
|
+
*/
|
|
603
|
+
count<T extends Document>(
|
|
604
|
+
coll: MongoCollection<T>,
|
|
605
|
+
filter: Filter<MongoDocWithId<T>>
|
|
606
|
+
): Promise<number> {
|
|
607
|
+
return this.timingQuery({
|
|
608
|
+
query: async () => {
|
|
609
|
+
return this.getCollection(coll).countDocuments(filter, { session: this.session })
|
|
610
|
+
},
|
|
611
|
+
desc() {
|
|
612
|
+
return {
|
|
613
|
+
op: 'count',
|
|
614
|
+
coll: coll.collectionName,
|
|
615
|
+
filter
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
})
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
/**
|
|
622
|
+
* 分页查询。谨慎使用,不建议对规模较大的数据查询直接使用分页。
|
|
623
|
+
* @param coll 集合信息
|
|
624
|
+
* @param filter 过滤条件
|
|
625
|
+
* @param opts 分页参数
|
|
626
|
+
*/
|
|
627
|
+
async paginate<T extends Document>(
|
|
628
|
+
coll: MongoCollection<T>,
|
|
629
|
+
filter: Filter<MongoDocWithId<T>>,
|
|
630
|
+
opts: {
|
|
631
|
+
/**
|
|
632
|
+
* 页码,从1开始,第一页是 1
|
|
633
|
+
*/
|
|
634
|
+
pn: number
|
|
635
|
+
/**
|
|
636
|
+
* 每页的数据量大小
|
|
637
|
+
*/
|
|
638
|
+
pz: number
|
|
639
|
+
/**
|
|
640
|
+
* 排序规则,按先后顺序放入,每个规则是一个元组,第一个元素是字段名称,第二个元素是顺序
|
|
641
|
+
*/
|
|
642
|
+
orderBy?: Array<[keyof MongoDocWithId<T>, 'asc' | 'desc']>
|
|
643
|
+
}
|
|
644
|
+
): Promise<MongoPage<MongoDocWithId<T>>> {
|
|
645
|
+
validate(opts, {
|
|
646
|
+
pn: [notNull(), min(1)],
|
|
647
|
+
pz: [notNull(), min(1)]
|
|
648
|
+
})
|
|
649
|
+
const start = new Date().getTime()
|
|
650
|
+
try {
|
|
651
|
+
const offset = (opts.pn - 1) * opts.pz
|
|
652
|
+
const res = await Promise.all([
|
|
653
|
+
this.find(coll, filter, { offset, limit: opts.pz, orderBy: opts.orderBy }),
|
|
654
|
+
this.count(coll, filter)
|
|
655
|
+
])
|
|
656
|
+
const [list, total] = res
|
|
657
|
+
return { list, total }
|
|
658
|
+
} finally {
|
|
659
|
+
if (this.config.slowQueryWarn) {
|
|
660
|
+
const cost = new Date().getTime() - start
|
|
661
|
+
if (cost > this.config.slowQueryMs) {
|
|
662
|
+
getLogger().warn(
|
|
663
|
+
`[mongodb slow query] ${cost}ms ${JSON.stringify({
|
|
664
|
+
op: 'paginate',
|
|
665
|
+
coll: coll.collectionName,
|
|
666
|
+
filter,
|
|
667
|
+
opts
|
|
668
|
+
})}`
|
|
669
|
+
)
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
}
|