UNPKG

@joktec/mongo

Version:

JokTec - Mongo Service

293 lines 12.9 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.MongoRepo = void 0; const core_1 = require("@joktec/core"); const utils_1 = require("@joktec/utils"); const lodash_1 = require("lodash"); const helpers_1 = require("./helpers"); const mongo_exception_1 = require("./mongo.exception"); const mongo_service_1 = require("./mongo.service"); let MongoRepo = class MongoRepo { constructor(mongoService, schema, conId = core_1.DEFAULT_CON_ID) { this.mongoService = mongoService; this.schema = schema; this.conId = conId; } async onModuleInit() { this.logService.setContext(this.constructor.name); } get model() { return this.mongoService.getModel(this.schema); } transform(docs) { if ((0, lodash_1.isNil)(docs)) return null; if ((0, lodash_1.isArray)(docs) && !docs.length) return []; const transformDocs = (0, utils_1.plainToInstance)(this.schema, (0, utils_1.toArray)(docs), { ignoreDecorators: true }); return ((0, lodash_1.isArray)(docs) ? transformDocs : transformDocs[0]); } qb(query, options = {}) { const qb = this.model.find(); qb.setOptions({ ...options }); const { limit, offset } = helpers_1.MongoHelper.parsePagination(query); if (query?.near) qb.center(query.near); if (query?.keyword) qb.search(query.keyword); qb.where(Object.assign({}, query?.condition || {})); if (query?.select) qb.select(query.select); if (query?.sort) qb.sort(helpers_1.MongoHelper.parseSort(query.sort)); if (offset !== undefined) qb.skip(offset); if (limit !== undefined) qb.limit(limit); if (query?.populate) qb.populate(helpers_1.MongoHelper.parsePopulate(query.populate)); return qb.lean(); } cursor(query, options = {}) { const qb = this.model.find(); qb.setOptions({ ...options }); const { limit, offset } = helpers_1.MongoHelper.parsePagination(query); if (query?.near) qb.center(query.near); if (query?.keyword) qb.search(query.keyword); if (query?.condition) qb.where(helpers_1.MongoHelper.parseFilter(query.condition)); if (query?.select) qb.select(helpers_1.MongoHelper.parseProjection(query.select)); if (query?.sort) qb.sort(helpers_1.MongoHelper.parseSort(query.sort)); if (offset !== undefined) qb.skip(offset); if (limit !== undefined) qb.limit(limit); if (query?.populate) qb.populate(helpers_1.MongoHelper.parsePopulate(query.populate)); return qb.lean().cursor(); } pipeline(query, options) { const aggregations = this.model.aggregate(); const { limit, offset } = helpers_1.MongoHelper.parsePagination(query); if (options) aggregations.option({ ...options }); if (query?.near) helpers_1.MongoPipeline.near(query.near).map(near => aggregations.near(near)); if (query?.keyword) aggregations.match(helpers_1.MongoPipeline.search(query.keyword)); if (query?.condition) aggregations.match(helpers_1.MongoPipeline.match(query.condition)); if (query?.select) aggregations.project(helpers_1.MongoPipeline.projection(query.select)); if (query?.sort) aggregations.sort(helpers_1.MongoPipeline.sort(query.sort)); if (offset !== undefined) aggregations.skip(offset); if (limit !== undefined) aggregations.limit(limit); if (query?.populate) helpers_1.MongoPipeline.lookup(query.populate, this.model).map(p => aggregations.append(p)); if (query?.aggregations?.length) aggregations.append(...query.aggregations); return aggregations; } async paginate(query, options = {}) { const findQuery = { ...query }; const countQuery = (0, lodash_1.omit)(query, ['select', 'page', 'limit', 'offset', 'sort']); const [items, total] = await Promise.all([this.find(findQuery, options), this.count(countQuery, options)]); return { items, total }; } async find(query, options = {}) { const docs = await this.qb(query, options).find().exec(); return this.transform(docs); } async count(query, options = {}) { const processQuery = (0, lodash_1.omit)(query, ['select', 'page', 'limit', 'offset', 'sort']); const qb = this.qb(processQuery, options); return query.near ? qb.estimatedDocumentCount() : qb.countDocuments(); } async findOne(cond, query = {}, options = {}) { const condition = helpers_1.MongoHelper.parseSimpleCondition(cond); const mergeQuery = Object.assign({}, query, { condition }); const doc = await this.qb(mergeQuery, options).findOne().exec(); return this.transform(doc); } async create(body, options = {}) { const transformBody = this.transform(body); const doc = await this.model.create(transformBody); return this.findOne(doc._id, options); } async update(cond, body, options = {}) { const condition = helpers_1.MongoHelper.parseSimpleCondition(cond); const transformBody = this.transform(body); const _options = Object.assign({}, helpers_1.UPDATE_OPTIONS, options); const doc = await this.qb({ condition }, _options).findOneAndUpdate(transformBody).exec(); return this.transform(doc); } async updateMany(condition, body, options = {}) { const transformBody = this.transform(body); const _options = Object.assign({}, helpers_1.UPDATE_OPTIONS, options); await this.qb({ condition }, _options).updateMany(transformBody).exec(); return this.find({ condition }); } async delete(cond, options = {}) { const condition = helpers_1.MongoHelper.parseSimpleCondition(cond); const doc = await this.qb().destroyOne(condition, options).exec(); return this.transform(doc); } async deleteMany(cond, options = {}) { const docs = await this.qb({ condition: cond }).exec(); await this.model.destroyMany(cond, options).exec(); return this.transform(docs); } async restore(cond, options = {}) { const condition = helpers_1.MongoHelper.parseSimpleCondition(cond); const doc = await this.qb().restore(condition, options).exec(); return this.transform(doc); } async upsert(body, onConflicts, options = {}) { const fields = onConflicts?.length ? onConflicts : ['_id']; const transformBody = this.transform(body); const condition = (0, lodash_1.pick)(body, fields); const _options = Object.assign({}, helpers_1.UPSERT_OPTIONS, options); const doc = await this.qb({ condition }, _options).findOneAndUpdate(transformBody).exec(); return this.transform(doc); } async bulkUpsert(docs, onConflicts, options = {}) { const fields = onConflicts?.length ? onConflicts : ['_id']; const transformBody = this.transform(docs); const chunkSize = (0, utils_1.toInt)(options?.chunkSize, 1000); const chunkItems = (0, lodash_1.chunk)(transformBody, chunkSize); const results = []; for (const chunkItem of chunkItems) { const bulkDocs = chunkItem.map((doc) => { const updateDoc = {}; Object.keys(doc).forEach(key => { if (!key.startsWith('$')) { if (!updateDoc.$set) updateDoc.$set = {}; updateDoc.$set[key] = doc[key]; } }); return { updateOne: { filter: (0, lodash_1.pick)(doc, fields), update: updateDoc, upsert: true } }; }); const result = await this.model.bulkWrite(bulkDocs, options); const newIds = [...Object.values(result.upsertedIds), ...Object.values(result.insertedIds)]; const newItems = await this.find({ condition: { _id: { $in: newIds } } }); results.push(newItems); } return results.flat(); } async aggregate(pipeline, options = {}) { const { autoTransform = true, transformFn } = options; const docs = await this.model.aggregate(pipeline, options).exec(); if (transformFn) return options.transformFn(docs); if (autoTransform) return this.transform(docs); return docs; } }; exports.MongoRepo = MongoRepo; __decorate([ (0, core_1.Inject)(), __metadata("design:type", core_1.Reflector) ], MongoRepo.prototype, "reflector", void 0); __decorate([ (0, core_1.Inject)(), __metadata("design:type", core_1.ConfigService) ], MongoRepo.prototype, "configService", void 0); __decorate([ (0, core_1.Inject)(), __metadata("design:type", core_1.LogService) ], MongoRepo.prototype, "logService", void 0); __decorate([ mongo_exception_1.MongoCatch, __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], MongoRepo.prototype, "paginate", null); __decorate([ mongo_exception_1.MongoCatch, __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], MongoRepo.prototype, "find", null); __decorate([ mongo_exception_1.MongoCatch, __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], MongoRepo.prototype, "count", null); __decorate([ mongo_exception_1.MongoCatch, __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object, Object]), __metadata("design:returntype", Promise) ], MongoRepo.prototype, "findOne", null); __decorate([ mongo_exception_1.MongoCatch, __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], MongoRepo.prototype, "create", null); __decorate([ mongo_exception_1.MongoCatch, __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object, Object]), __metadata("design:returntype", Promise) ], MongoRepo.prototype, "update", null); __decorate([ mongo_exception_1.MongoCatch, __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], MongoRepo.prototype, "delete", null); __decorate([ mongo_exception_1.MongoCatch, __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], MongoRepo.prototype, "deleteMany", null); __decorate([ mongo_exception_1.MongoCatch, __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], MongoRepo.prototype, "restore", null); __decorate([ mongo_exception_1.MongoCatch, __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Array, Object]), __metadata("design:returntype", Promise) ], MongoRepo.prototype, "upsert", null); __decorate([ mongo_exception_1.MongoCatch, __metadata("design:type", Function), __metadata("design:paramtypes", [Array, Array, Object]), __metadata("design:returntype", Promise) ], MongoRepo.prototype, "bulkUpsert", null); __decorate([ mongo_exception_1.MongoCatch, __metadata("design:type", Function), __metadata("design:paramtypes", [Array, Object]), __metadata("design:returntype", Promise) ], MongoRepo.prototype, "aggregate", null); exports.MongoRepo = MongoRepo = __decorate([ (0, core_1.Injectable)(), __metadata("design:paramtypes", [mongo_service_1.MongoService, Object, String]) ], MongoRepo); //# sourceMappingURL=mongo.repo.js.map