updated filtering code

This commit is contained in:
2025-05-02 16:27:52 +05:30
parent 4153bd2412
commit c84cd055d4
10 changed files with 160 additions and 211 deletions

View File

@@ -1,111 +1,67 @@
import mongoose from 'mongoose';
type ParsedQuery = Array<
Record<string, Record<'$eq' | '$ne' | '$in' | '$nin', string | Date | Object>>
>;
type MongoFilter = Record<string, any>;
function convertValue(value: any) {
if (mongoose.Types.ObjectId.isValid(value)) {
return mongoose.Types.ObjectId.createFromHexString(value);
function formulaToMongoFilter(formula: string): MongoFilter {
// Split the formula into parts
const operatorMatch = formula.match(/([^!<>=]+)([!<>=]+)(.+)/);
if (!operatorMatch) {
throw new Error(`Invalid formula format: ${formula}`);
}
const [, field, operator, value] = operatorMatch;
const trimmedField = field.trim();
const trimmedValue = value.trim();
if (trimmedField === 'tenantId') return {};
// Convert value to appropriate type (date or number if possible)
let parsedValue: any = trimmedValue;
if (/^\d{4}-\d{2}-\d{2}$/.test(trimmedValue)) {
// Check if it's a date (ISO format)
parsedValue = new Date(trimmedValue);
} else if (!isNaN(Number(trimmedValue))) {
// Check if it's a number
parsedValue = Number(trimmedValue);
} else if (
!isNaN(parseInt(value)) &&
parseInt(value).toString().length == value.toString().length
typeof parsedValue === 'string' &&
mongoose.Types.ObjectId.isValid(parsedValue)
) {
return parseInt(value);
} else if (!isNaN(Date.parse(value))) {
return new Date(value);
} else if (value === 'true') {
return true;
} else if (value === 'false') {
return false;
} else {
return value;
parsedValue = new mongoose.Types.ObjectId(parsedValue);
} else if (parsedValue === 'true') {
parsedValue = true;
} else if (parsedValue === 'false') {
parsedValue = false;
} else if (parsedValue === 'null') {
parsedValue = null;
}
// Convert operator to MongoDB operator
switch (operator) {
case '=':
return { [trimmedField]: { $eq: parsedValue } };
case '!=':
return { [trimmedField]: { $ne: parsedValue } };
case '>':
return { [trimmedField]: { $gt: parsedValue } };
case '<':
return { [trimmedField]: { $lt: parsedValue } };
case '>=':
return { [trimmedField]: { $gte: parsedValue } };
case '<=':
return { [trimmedField]: { $lte: parsedValue } };
default:
throw new Error(`Unsupported operator: ${operator}`);
}
}
export function parse(query: string, validFields: Array<string>): ParsedQuery {
const result = [];
export function parse(formulas: string[]): MongoFilter {
const parsedQuery: MongoFilter = formulas.reduce((filter, formula) => {
const newFilter = formulaToMongoFilter(formula);
return { ...filter, ...newFilter };
}, {});
let currentStage = 'field';
let token = '';
let field = '';
let op = '';
let value = '';
let valueArr = [];
for (let i = 0; i < query.length; i++) {
let char = query[i];
if (currentStage === 'field') {
if (char === '=' || char === '!') {
field = token;
token = '';
currentStage = 'value';
if (char === '=') {
op = '$eq';
} else {
op = '$ne';
i++;
}
continue;
}
token += char;
}
if (currentStage === 'value') {
if (char === '[') {
currentStage = 'valueArr';
continue;
}
if (char === ',' || i == query.length - 1) {
if (i == query.length - 1) token += char;
value = token;
result.push({ [field]: { [op]: convertValue(value) } });
token = '';
field = '';
op = '';
currentStage = 'field';
continue;
}
token += char;
}
if (currentStage === 'valueArr') {
if (char === ',') {
valueArr.push(convertValue(token));
token = '';
continue;
}
if (char === ']') {
valueArr.push(convertValue(token));
result.push({
[field]: { [op === '$eq' ? '$in' : '$nin']: valueArr },
});
token = '';
field = '';
op = '';
valueArr = [];
currentStage = 'field';
i++;
continue;
}
token += char;
}
}
console.log(result);
return result;
return parsedQuery;
}