@joktec/mongo
Version:
JokTec - Mongo Service
293 lines • 12.9 kB
JavaScript
;
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