mongoose-sort-encrypted-field
Advanced tools
Comparing version 0.1.6 to 0.2.0
declare const Base2N: any; | ||
declare const documentsBinarySearch: any, getAverageSortId: any, updateSortFieldsForDocument: any; | ||
declare const getModelsQueue: any; | ||
declare const mongoose: any; | ||
declare function sortEncryptedFields(schema: { | ||
pre: Function; | ||
post: Function; | ||
add: Function; | ||
options: { | ||
sortEncryptedFieldsOptions: any; | ||
}; | ||
paths: { | ||
[fieldName: string]: { | ||
options: { | ||
get: Function; | ||
sortFieldName: string; | ||
}; | ||
}; | ||
}; | ||
}, options?: { | ||
redisOptions: any; | ||
noOfCharsToIncreaseOnSaturation?: number; | ||
ignoreCases?: boolean; | ||
silent: boolean; | ||
revaluateAllThreshold?: number; | ||
revaluateAllCountThreshold?: number; | ||
}): void; | ||
declare function sortEncryptedFields(schema: Schema, pluginOptions: PluginOptions): void; | ||
declare function getModelWithSortEncryptedFieldsPlugin(documentName: any, schema: any, pluginOptions: any): any; |
@@ -11,47 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
const Base2N = require("@navpreetdevpuri/base-2-n"); | ||
const { documentsBinarySearch, getAverageSortId, updateSortFieldsForDocument } = require("./utils"); | ||
const getModelsQueue = require("./modelsQueue"); | ||
// It is not in package.json to keep it at the same version as the package user's mongoose version to avoid compatibility issues | ||
// mongoose is not in package.json to avoid compatibility issues with npm package user | ||
const mongoose = require("mongoose"); | ||
/* | ||
options: | ||
redisOptions: | ||
default: null; | ||
Any options which we can pass to ioredis constructor; (https://www.npmjs.com/package/ioredis) | ||
noOfCharsToIncreaseOnSaturation?: number; | ||
default: 2; | ||
Number of chars to increase on saturation, for example, | ||
for `04` and `05`, first we can see there is no whole number between those | ||
so, It append extra digit at the end and it becomes `040` and `050` and the average is `045`. | ||
In the base `2^16` number system, getting a saturation like that is mathematically very unlikely. | ||
ignoreCases?: boolean; | ||
default: false; | ||
To ignore cases. | ||
silent?: boolean; | ||
default: false; | ||
Flag to turn on/off console info logs | ||
revaluateAllThreshold?: number; | ||
default: 0.5 | ||
If number of documents without sort ID divides by total number of documents is less then this threshold | ||
Then it will get all values, sort them, generate sort ID for all at equal distance 0 to 2^16 | ||
For example if we have 3 documents and we can 00 to 20 sort ID | ||
then those documents will have 05 10 15 sort ID | ||
revaluateAllCountThreshold?: number; | ||
default: 100 | ||
If total number of documents are less then this value | ||
then it will regenerat sort ID same way as revaluateAllThreshold | ||
*/ | ||
function sortEncryptedFields(schema, options = { | ||
redisOptions: null, | ||
noOfCharsToIncreaseOnSaturation: 2, | ||
ignoreCases: false, | ||
silent: false, | ||
revaluateAllThreshold: 0.5, | ||
revaluateAllCountThreshold: 100, | ||
}) { | ||
const { redisOptions = null, noOfCharsToIncreaseOnSaturation = 2, ignoreCases = false, silent = false, revaluateAllThreshold = 0.5, revaluateAllCountThreshold = 100, } = options; | ||
if (!redisOptions) { | ||
throw "Please provide redisOptions in plugin options. Which is same as constructor of ioredis npm package"; | ||
} | ||
const sortEncryptedFieldsOptions = Object.assign({ redisOptions: null, noOfCharsToIncreaseOnSaturation: 2, ignoreCases: false, silent: false, revaluateAllThreshold: 0.5 }, options); | ||
function sortEncryptedFields(schema, pluginOptions) { | ||
const sortEncryptedFieldsOptions = Object.assign(Object.assign({}, PLUGIN_OPTIONS), pluginOptions); | ||
const { redisQueueClientOptions, ignoreCases, noOfCharsToIncreaseOnSaturation } = sortEncryptedFieldsOptions; | ||
const sortFields = {}; | ||
@@ -75,3 +35,3 @@ const decrypters = {}; | ||
sortEncryptedFieldsOptions.decrypters = decrypters; | ||
const modelsQueue = getModelsQueue(redisOptions); | ||
const modelsQueue = getModelsQueue(redisQueueClientOptions); | ||
sortEncryptedFieldsOptions.modelsQueue = modelsQueue; | ||
@@ -82,3 +42,3 @@ schema.options.sortEncryptedFieldsOptions = sortEncryptedFieldsOptions; | ||
for (const [fieldName, sortFieldName] of Object.entries(sortFields)) { | ||
yield modelsQueue.addJob(this.constructor.modelName, { | ||
yield modelsQueue.addJob(`${this.constructor.modelName}${sortFieldName}`, { | ||
objectId: doc._id, | ||
@@ -98,3 +58,3 @@ fieldName, | ||
const update = this.getUpdate(); | ||
for (const fieldName of Object.keys(sortFields)) { | ||
for (const fieldName in sortFields) { | ||
const sortFieldName = sortFields[fieldName]; | ||
@@ -115,3 +75,3 @@ if (update.$set && update.$set[sortFieldName]) { | ||
const update = this.getUpdate(); | ||
for (const fieldName of Object.keys(sortFields)) { | ||
for (const fieldName in sortFields) { | ||
const sortFieldName = sortFields[fieldName]; | ||
@@ -126,3 +86,3 @@ if (update.$set && update.$set[sortFieldName]) { | ||
const fieldValue = document[fieldName]; | ||
yield modelsQueue.addJob(this.modelName.model, { | ||
yield modelsQueue.addJob(`${this.modelName.model}${sortFieldName}`, { | ||
objectId: document._id, | ||
@@ -144,3 +104,3 @@ fieldName, | ||
const update = this.getUpdate(); | ||
for (const fieldName of Object.keys(sortFields)) { | ||
for (const fieldName in sortFields) { | ||
const sortFieldName = sortFields[fieldName]; | ||
@@ -161,3 +121,3 @@ if (update.$set && update.$set[sortFieldName]) { | ||
const update = this.getUpdate(); | ||
for (const fieldName of Object.keys(sortFields)) { | ||
for (const fieldName in sortFields) { | ||
const sortFieldName = sortFields[fieldName]; | ||
@@ -173,3 +133,3 @@ if (update.$set && update.$set[sortFieldName]) { | ||
for (let i = 0; i < documents.length; i += 1) { | ||
yield modelsQueue.addJob(this.model.modelName, { | ||
yield modelsQueue.addJob(`${this.model.modelName}${sortFieldName}`, { | ||
objectId: documents[i]._id, | ||
@@ -194,3 +154,5 @@ fieldName, | ||
const model = mongoose.model(documentName, schema); | ||
modelsQueue.registerModel(model); | ||
for (const fieldName in sortFields) { | ||
modelsQueue.registerGroup(`${model.modelName}${sortFields[fieldName]}`, model); | ||
} | ||
model | ||
@@ -202,3 +164,3 @@ .find({}) | ||
const {} = model.schema.options; | ||
for (const fieldName of Object.keys(sortFields)) { | ||
for (const fieldName in sortFields) { | ||
const sortFieldName = sortFields[fieldName]; | ||
@@ -211,4 +173,4 @@ const noOfDocumentsWithoutSortId = yield model | ||
noOfDocumentsWithoutSortId / noOfTotalDocuments > revaluateAllThreshold) { | ||
yield modelsQueue.removeAllJobs(model.modelName); | ||
yield modelsQueue.addJob(model.modelName, { | ||
yield modelsQueue.removeAllJobs(`${model.modelName}${sortFieldName}`); | ||
yield modelsQueue.addJob(`${model.modelName}${sortFieldName}`, { | ||
generateSortIdForAllDocuments: true, | ||
@@ -225,3 +187,3 @@ fieldName, | ||
const fieldValue = documents[i][fieldName]; | ||
yield modelsQueue.addJob(model.modelName, { | ||
yield modelsQueue.addJob(`${model.modelName}${sortFieldName}`, { | ||
objectId: documents[i]._id, | ||
@@ -228,0 +190,0 @@ fieldName, |
@@ -0,2 +1,22 @@ | ||
declare const RedisQueueClient: any; | ||
declare const Redis: any; | ||
declare const defaultRedisKeyPrefix = "mongoose-sort-encrypted-field"; | ||
declare let modelsQueue: any; | ||
declare class ModelsQueue { | ||
client: typeof RedisQueueClient; | ||
noOfGroups: number; | ||
groupIdToModelMap: {}; | ||
constructor(redisQueueClientOptions: any); | ||
handleMessage({ data, context: { lock: { groupId }, }, }: { | ||
data: any; | ||
context: { | ||
lock: { | ||
groupId: any; | ||
}; | ||
}; | ||
}): Promise<void>; | ||
addJob(groupId: any, data: any): Promise<void>; | ||
registerGroup(model: any, groupId: any): void; | ||
removeAllJobs(modelName: any): Promise<void>; | ||
} | ||
declare function getModelsQueue(redisOptions: any): any; | ||
export = getModelsQueue; |
@@ -1,2 +0,1 @@ | ||
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
@@ -13,15 +12,19 @@ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
const Redis = require("ioredis"); | ||
const { updateSortFieldsForDocument, generateSortIdForAllDocuments } = require("./utils"); | ||
const redisKeyPrefix = "mongoose-sort-encrypted-field"; | ||
const defaultRedisKeyPrefix = "mongoose-sort-encrypted-field"; | ||
let modelsQueue; | ||
class ModelsQueue { | ||
constructor(redisOptions) { | ||
this.modelNameToModelMap = {}; | ||
const redis = new Redis(redisOptions); | ||
constructor(redisQueueClientOptions) { | ||
this.groupIdToModelMap = {}; | ||
redisQueueClientOptions = Object.assign(Object.assign({}, REDIS_QUEUE_CLIENT_OPTIONS), redisQueueClientOptions); | ||
const { redis, batchSize, groupVisibilityTimeoutMs, pollingTimeoutMs, consumerCount, redisKeyPrefix } = redisQueueClientOptions; | ||
let redisClient = redis; | ||
if (!(redis instanceof Redis)) { | ||
redisClient = new Redis(redis); | ||
} | ||
this.client = new RedisQueueClient({ | ||
redis, | ||
batchSize: 1, | ||
groupVisibilityTimeoutMs: 60000, | ||
pollingTimeoutMs: 10000, | ||
consumerCount: 1, | ||
redis: redisClient, | ||
batchSize, | ||
groupVisibilityTimeoutMs, | ||
pollingTimeoutMs, | ||
consumerCount, | ||
redisKeyPrefix, | ||
@@ -33,3 +36,3 @@ }); | ||
return __awaiter(this, void 0, void 0, function* () { | ||
data.model = modelsQueue.modelNameToModelMap[groupId]; | ||
data.model = modelsQueue.groupIdToModelMap[groupId]; | ||
if (!data.model.schema.options.sortEncryptedFieldsOptions.silent) { | ||
@@ -46,10 +49,10 @@ const noOfPendingJobs = (yield modelsQueue.client.getMetrics(100)).topMessageGroupsMessageBacklogLength; | ||
} | ||
addJob(modelName, data) { | ||
addJob(groupId, data) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield this.client.send({ data, groupId: modelName }); | ||
yield this.client.send({ groupId, data }); | ||
}); | ||
} | ||
registerModel(model) { | ||
if (!this.modelNameToModelMap[model.modelName]) { | ||
this.modelNameToModelMap[model.modelName] = model; | ||
registerGroup(model, groupId) { | ||
if (!this.groupIdToModelMap[groupId]) { | ||
this.groupIdToModelMap[groupId] = model; | ||
} | ||
@@ -59,5 +62,7 @@ } | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const keys = yield this.client.redis.keys(`${redisKeyPrefix}::msg-group-queue::${modelName}`); | ||
const keys = yield this.client.redis.keys(`${defaultRedisKeyPrefix}::msg-group-queue::${modelName}`); | ||
var pipeline = this.client.redis.pipeline(); | ||
keys.forEach(function (key) { pipeline.del(key); }); | ||
keys.forEach(function (key) { | ||
pipeline.del(key); | ||
}); | ||
pipeline.exec(); | ||
@@ -73,2 +78,1 @@ }); | ||
} | ||
module.exports = getModelsQueue; |
@@ -21,2 +21,1 @@ declare function documentsBinarySearch(model: any, fieldName: any, fieldValue: any, sortFieldName: any, ignoreCases: any): Promise<{ | ||
}): Promise<void>; | ||
export { documentsBinarySearch, getAverageSortId, updateSortFieldsForDocument, generateSortIdForAllDocuments }; |
@@ -1,2 +0,1 @@ | ||
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
@@ -11,5 +10,2 @@ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.generateSortIdForAllDocuments = exports.updateSortFieldsForDocument = exports.getAverageSortId = exports.documentsBinarySearch = void 0; | ||
const Base2N = require("@navpreetdevpuri/base-2-n"); | ||
function documentsBinarySearch(model, fieldName, fieldValue, sortFieldName, ignoreCases) { | ||
@@ -112,3 +108,2 @@ return __awaiter(this, void 0, void 0, function* () { | ||
} | ||
exports.documentsBinarySearch = documentsBinarySearch; | ||
function getAverageSortId(predecessorSortId, successorSortId, noOfCharsToIncreaseOnSaturation) { | ||
@@ -140,3 +135,2 @@ if (!predecessorSortId) { | ||
} | ||
exports.getAverageSortId = getAverageSortId; | ||
function updateSortFieldsForDocument({ objectId, model, fieldName, fieldValue, sortFieldName, ignoreCases, noOfCharsToIncreaseOnSaturation, }) { | ||
@@ -163,3 +157,2 @@ return __awaiter(this, void 0, void 0, function* () { | ||
} | ||
exports.updateSortFieldsForDocument = updateSortFieldsForDocument; | ||
function generateSortIdForAllDocuments({ model, fieldName, sortFieldName, ignoreCases }) { | ||
@@ -193,2 +186,1 @@ return __awaiter(this, void 0, void 0, function* () { | ||
} | ||
exports.generateSortIdForAllDocuments = generateSortIdForAllDocuments; |
{ | ||
"name": "mongoose-sort-encrypted-field", | ||
"version": "0.1.6", | ||
"version": "0.2.0", | ||
"description": "Mongoose plugin to enable sorting on encrypted fields", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -31,3 +31,3 @@ # mongoose-sort-encrypted-field | ||
const User = getModelWithSortEncryptedFieldsPlugin("User", userSchema, { | ||
redisOptions: { host: "localhost", port: 6379 }, | ||
redisQueueClientOptions: { redis: "redis://localhost:6379" }, | ||
ignoreCases: true, | ||
@@ -47,22 +47,41 @@ }); | ||
1. `redisOptions: Any;` default: `null` <br> | ||
Any options which we can pass to [ioredis]((https://www.npmjs.com/package/ioredis) ) constructor; | ||
2. `noOfCharsToIncreaseOnSaturation?: number;` default: `2` <br> | ||
Number of chars to increase on saturation, for example, | ||
for `04` and `05`, first we can see there is no whole number between those | ||
so, It append extra digit at the end and it becomes `040` and `050` and the average is `045`. | ||
In the base `2^16` number system, getting a saturation like that is mathematically very unlikely. | ||
3. `ignoreCases?: boolean;` default: `false` <br> | ||
To ignore cases. | ||
4. `silent?: boolean;` default: `false` <br> | ||
Flag to turn on/off console info logs | ||
5. `revaluateAllThreshold?: number;` default: `0.5` <br> | ||
If the number of documents without sort ID divides by the total number of documents is less than this threshold | ||
Then it will get all values, sort them, generate sort ID for all at equal distance 0 to 2^16 | ||
For example if we have 3 documents and we can 00 to 20 sort ID | ||
then those documents will have 05 10 15 sort ID | ||
6. `revaluateAllCountThreshold?: number;` default: `100` <br> | ||
If the total number of documents is less than this value | ||
then it will regenerate the sort ID the same way as revaluateAllThreshold | ||
1. `redisQueueClientOptions: RedisQueueClientOptions;` default: | ||
``` | ||
{ | ||
redis: new Redis(), | ||
batchSize: 10, | ||
groupVisibilityTimeoutMs: 60000, | ||
pollingTimeoutMs: 10000, | ||
// Better to have consumerCount in a balance of maximum fields we have to sort vs Resources usage for multiple consumers | ||
consumerCount: 1, | ||
redisKeyPrefix: "mongoose-sort-encrypted-field", | ||
} | ||
``` | ||
<br> | ||
Any options which we can pass to [redis-ordered-queue](<(https://www.npmjs.com/package/redis-ordered-queue)>) constructor and redis options can be an instance of [ioredis](https://www.npmjs.com/package/ioredis) or any value that we can pass to ioredis constructor | ||
2. `noOfCharsToIncreaseOnSaturation?: number;` default: `2` <br> | ||
Number of chars to increase on saturation, for example, | ||
for `04` and `05`, first, we can see there is no whole number between those | ||
so, It appends an extra digit at the end and it becomes `040` and `050` and the average is `045`. | ||
In the base `2^16` number system, getting a saturation like that is mathematically very unlikely. | ||
3. `ignoreCases?: boolean;` default: `false` <br> | ||
To ignore cases. | ||
4. `silent?: boolean;` default: `false` <br> | ||
Flag to turn on/off console info logs | ||
5. `revaluateAllThreshold?: number;` default: `0.5` <br> | ||
If the number of documents without sort ID divided by the total number of documents is less than this threshold | ||
Then it will get all values, sort them, and generate sort ID for all at equal distances 0 to 2^16 | ||
For example, if we have 3 documents and we can 00 to 20 sort ID | ||
then those documents will have 05 10 15 sort ID | ||
6. `revaluateAllCountThreshold?: number;` default: `100` <br> | ||
If the total number of documents is less than this value | ||
then it will regenerate the sort ID the same way as revaluateAllThreshold | ||
# How does it work? | ||
@@ -69,0 +88,0 @@ |
123
src/index.ts
const Base2N = require("@navpreetdevpuri/base-2-n"); | ||
const { documentsBinarySearch, getAverageSortId, updateSortFieldsForDocument } = require("./utils"); | ||
const getModelsQueue = require("./modelsQueue"); | ||
// It is not in package.json to keep it at the same version as the package user's mongoose version to avoid compatibility issues | ||
// mongoose is not in package.json to avoid compatibility issues with npm package user | ||
const mongoose = require("mongoose"); | ||
/* | ||
options: | ||
redisOptions: | ||
default: null; | ||
Any options which we can pass to ioredis constructor; (https://www.npmjs.com/package/ioredis) | ||
noOfCharsToIncreaseOnSaturation?: number; | ||
default: 2; | ||
Number of chars to increase on saturation, for example, | ||
for `04` and `05`, first we can see there is no whole number between those | ||
so, It append extra digit at the end and it becomes `040` and `050` and the average is `045`. | ||
In the base `2^16` number system, getting a saturation like that is mathematically very unlikely. | ||
ignoreCases?: boolean; | ||
default: false; | ||
To ignore cases. | ||
silent?: boolean; | ||
default: false; | ||
Flag to turn on/off console info logs | ||
revaluateAllThreshold?: number; | ||
default: 0.5 | ||
If number of documents without sort ID divides by total number of documents is less then this threshold | ||
Then it will get all values, sort them, generate sort ID for all at equal distance 0 to 2^16 | ||
For example if we have 3 documents and we can 00 to 20 sort ID | ||
then those documents will have 05 10 15 sort ID | ||
revaluateAllCountThreshold?: number; | ||
default: 100 | ||
If total number of documents are less then this value | ||
then it will regenerat sort ID same way as revaluateAllThreshold | ||
*/ | ||
function sortEncryptedFields( | ||
schema: { | ||
pre: Function; | ||
post: Function; | ||
add: Function; | ||
options: { sortEncryptedFieldsOptions }; | ||
paths: { | ||
[fieldName: string]: { | ||
options: { get: Function; sortFieldName: string }; | ||
}; | ||
}; | ||
}, | ||
options: { | ||
redisOptions: any; | ||
noOfCharsToIncreaseOnSaturation?: number; | ||
ignoreCases?: boolean; | ||
silent: boolean; | ||
revaluateAllThreshold?: number; | ||
revaluateAllCountThreshold?: number; | ||
} = { | ||
redisOptions: null, | ||
noOfCharsToIncreaseOnSaturation: 2, | ||
ignoreCases: false, | ||
silent: false, | ||
revaluateAllThreshold: 0.5, | ||
revaluateAllCountThreshold: 100, | ||
} | ||
) { | ||
const { | ||
redisOptions = null, | ||
noOfCharsToIncreaseOnSaturation = 2, | ||
ignoreCases = false, | ||
silent = false, | ||
revaluateAllThreshold = 0.5, | ||
revaluateAllCountThreshold = 100, | ||
} = options; | ||
function sortEncryptedFields(schema: Schema, pluginOptions: PluginOptions) { | ||
const sortEncryptedFieldsOptions: SortEncryptedFieldsOptions = { | ||
...PLUGIN_OPTIONS, | ||
...pluginOptions, | ||
}; | ||
if (!redisOptions) { | ||
throw "Please provide redisOptions in plugin options. Which is same as constructor of ioredis npm package"; | ||
} | ||
const { redisQueueClientOptions, ignoreCases, noOfCharsToIncreaseOnSaturation } = sortEncryptedFieldsOptions; | ||
const sortEncryptedFieldsOptions: { | ||
redisOptions?: any; | ||
sortFields?: {}; | ||
decrypters?: {}; | ||
modelsQueue?: typeof modelsQueue; | ||
noOfCharsToIncreaseOnSaturation?: number; | ||
ignoreCases?: boolean; | ||
silent?: boolean; | ||
revaluateAllThreshold: number; | ||
} = { redisOptions: null, noOfCharsToIncreaseOnSaturation: 2, ignoreCases: false, silent: false, revaluateAllThreshold: 0.5, ...options }; | ||
const sortFields = {}; | ||
@@ -107,3 +32,3 @@ const decrypters = {}; | ||
const modelsQueue = getModelsQueue(redisOptions); | ||
const modelsQueue = getModelsQueue(redisQueueClientOptions); | ||
sortEncryptedFieldsOptions.modelsQueue = modelsQueue; | ||
@@ -115,3 +40,3 @@ | ||
for (const [fieldName, sortFieldName] of Object.entries(sortFields)) { | ||
await modelsQueue.addJob(this.constructor.modelName, { | ||
await modelsQueue.addJob(`${this.constructor.modelName}${sortFieldName}`, { | ||
objectId: doc._id, | ||
@@ -129,4 +54,4 @@ fieldName, | ||
schema.pre("updateOne", async function (res, next) { | ||
const update: { $set: { [key: string]: string } } = this.getUpdate(); | ||
for (const fieldName of Object.keys(sortFields)) { | ||
const update: Update = this.getUpdate(); | ||
for (const fieldName in sortFields) { | ||
const sortFieldName = sortFields[fieldName]; | ||
@@ -145,4 +70,4 @@ if (update.$set && update.$set[sortFieldName]) { | ||
schema.post("updateOne", async function (res, next) { | ||
const update: { $set: { [key: string]: string } } = this.getUpdate(); | ||
for (const fieldName of Object.keys(sortFields)) { | ||
const update: Update = this.getUpdate(); | ||
for (const fieldName in sortFields) { | ||
const sortFieldName = sortFields[fieldName]; | ||
@@ -157,3 +82,3 @@ if (update.$set && update.$set[sortFieldName]) { | ||
const fieldValue = document[fieldName]; | ||
await modelsQueue.addJob(this.modelName.model, { | ||
await modelsQueue.addJob(`${this.modelName.model}${sortFieldName}`, { | ||
objectId: document._id, | ||
@@ -174,3 +99,3 @@ fieldName, | ||
const update = this.getUpdate(); | ||
for (const fieldName of Object.keys(sortFields)) { | ||
for (const fieldName in sortFields) { | ||
const sortFieldName = sortFields[fieldName]; | ||
@@ -190,3 +115,3 @@ if (update.$set && update.$set[sortFieldName]) { | ||
const update = this.getUpdate(); | ||
for (const fieldName of Object.keys(sortFields)) { | ||
for (const fieldName in sortFields) { | ||
const sortFieldName = sortFields[fieldName]; | ||
@@ -202,3 +127,3 @@ if (update.$set && update.$set[sortFieldName]) { | ||
for (let i = 0; i < documents.length; i += 1) { | ||
await modelsQueue.addJob(this.model.modelName, { | ||
await modelsQueue.addJob(`${this.model.modelName}${sortFieldName}`, { | ||
objectId: documents[i]._id, | ||
@@ -224,3 +149,7 @@ fieldName, | ||
const model = mongoose.model(documentName, schema); | ||
modelsQueue.registerModel(model); | ||
for (const fieldName in sortFields) { | ||
modelsQueue.registerGroup(`${model.modelName}${sortFields[fieldName]}`, model); | ||
} | ||
model | ||
@@ -232,3 +161,3 @@ .find({}) | ||
const {} = model.schema.options; | ||
for (const fieldName of Object.keys(sortFields)) { | ||
for (const fieldName in sortFields) { | ||
const sortFieldName = sortFields[fieldName]; | ||
@@ -243,4 +172,4 @@ const noOfDocumentsWithoutSortId = await model | ||
) { | ||
await modelsQueue.removeAllJobs(model.modelName); | ||
await modelsQueue.addJob(model.modelName, { | ||
await modelsQueue.removeAllJobs(`${model.modelName}${sortFieldName}`); | ||
await modelsQueue.addJob(`${model.modelName}${sortFieldName}`, { | ||
generateSortIdForAllDocuments: true, | ||
@@ -256,3 +185,3 @@ fieldName, | ||
const fieldValue = documents[i][fieldName]; | ||
await modelsQueue.addJob(model.modelName, { | ||
await modelsQueue.addJob(`${model.modelName}${sortFieldName}`, { | ||
objectId: documents[i]._id, | ||
@@ -259,0 +188,0 @@ fieldName, |
const { RedisQueueClient } = require("redis-ordered-queue"); | ||
const Redis = require("ioredis"); | ||
const { updateSortFieldsForDocument, generateSortIdForAllDocuments } = require("./utils"); | ||
const redisKeyPrefix = "mongoose-sort-encrypted-field"; | ||
const defaultRedisKeyPrefix = "mongoose-sort-encrypted-field"; | ||
let modelsQueue; | ||
class ModelsQueue { | ||
client: typeof RedisQueueClient; | ||
modelNameToModelMap = {}; | ||
constructor(redisOptions) { | ||
const redis = new Redis(redisOptions); | ||
noOfGroups: number; | ||
groupIdToModelMap = {}; | ||
constructor(redisQueueClientOptions) { | ||
redisQueueClientOptions = { | ||
...REDIS_QUEUE_CLIENT_OPTIONS, | ||
...redisQueueClientOptions, | ||
}; | ||
const { redis, batchSize, groupVisibilityTimeoutMs, pollingTimeoutMs, consumerCount, redisKeyPrefix } = redisQueueClientOptions; | ||
let redisClient = redis; | ||
if (!(redis instanceof Redis)) { | ||
redisClient = new Redis(redis); | ||
} | ||
this.client = new RedisQueueClient({ | ||
redis, | ||
batchSize: 1, | ||
groupVisibilityTimeoutMs: 60000, | ||
pollingTimeoutMs: 10000, | ||
consumerCount: 1, | ||
redis: redisClient, | ||
batchSize, | ||
groupVisibilityTimeoutMs, | ||
pollingTimeoutMs, | ||
consumerCount, | ||
redisKeyPrefix, | ||
@@ -29,3 +39,3 @@ }); | ||
}) { | ||
data.model = modelsQueue.modelNameToModelMap[groupId]; | ||
data.model = modelsQueue.groupIdToModelMap[groupId]; | ||
if (!data.model.schema.options.sortEncryptedFieldsOptions.silent) { | ||
@@ -42,9 +52,9 @@ const noOfPendingJobs = (await modelsQueue.client.getMetrics(100)).topMessageGroupsMessageBacklogLength; | ||
async addJob(modelName, data) { | ||
await this.client.send({ data, groupId: modelName }); | ||
async addJob(groupId, data) { | ||
await this.client.send({ groupId, data }); | ||
} | ||
registerModel(model) { | ||
if (!this.modelNameToModelMap[model.modelName]) { | ||
this.modelNameToModelMap[model.modelName] = model; | ||
registerGroup(model, groupId) { | ||
if (!this.groupIdToModelMap[groupId]) { | ||
this.groupIdToModelMap[groupId] = model; | ||
} | ||
@@ -54,5 +64,7 @@ } | ||
async removeAllJobs(modelName) { | ||
const keys = await this.client.redis.keys(`${redisKeyPrefix}::msg-group-queue::${modelName}`); | ||
const keys = await this.client.redis.keys(`${defaultRedisKeyPrefix}::msg-group-queue::${modelName}`); | ||
var pipeline = this.client.redis.pipeline(); | ||
keys.forEach(function (key) { pipeline.del(key) }); | ||
keys.forEach(function (key) { | ||
pipeline.del(key); | ||
}); | ||
pipeline.exec(); | ||
@@ -68,3 +80,1 @@ } | ||
} | ||
export = getModelsQueue; |
@@ -1,2 +0,1 @@ | ||
const Base2N = require("@navpreetdevpuri/base-2-n"); | ||
async function documentsBinarySearch(model, fieldName, fieldValue, sortFieldName, ignoreCases) { | ||
@@ -191,4 +190,2 @@ const n = await model | ||
console.timeEnd("mongoose-sort-encrypted-field -> generateSortIdForAllDocuments() -> timeTaken: "); | ||
} | ||
export { documentsBinarySearch, getAverageSortId, updateSortFieldsForDocument, generateSortIdForAllDocuments }; | ||
} |
19
92
48034
988