Untitled

 avatar
unknown
plain_text
a year ago
4.7 kB
10
Indexable
const typeRuleConfig = {
    query_builder_rule: 'query-builder-rule',
    query_builder_group: 'query-builder-group',
}
const rulesConfig = {
    birthday: 'birthday',
    gender: 'gender'
}
const operatorConfig = {
    contains: 'contains',
    does_not_contain: 'does_not_contain',
}
const logicalOperatorConfig = {
    and: 'and',
    or: 'or'
}

const rules = {
    "name": "Customer",
    "id": "customer",
    "type": "query-builder-group",
    "query": {
        "logicalOperator": "or",
        "children": [
            {
                "type": "query-builder-rule",
                "query": {
                    "rule": "birthday",
                    "operator": "contains",
                    "operand": "Age Range",
                    "value": [
                        "35,44",
                        "25,34",
                        "18,24"
                    ]
                }
            },
            {
                "type": "query-builder-group",
                "query": {
                    "logicalOperator": "and",
                    "children": [
                        {
                            "type": "query-builder-rule",
                            "query": {
                                "rule": "gender",
                                "operator": "contains",
                                "operand": "Gender",
                                "value": [
                                    1,
                                    2,
                                    null
                                ]
                            }
                        },
                        {
                            "type": "query-builder-group",
                            "query": {
                                "logicalOperator": "and",
                                "children": [
                                    {
                                        "type": "query-builder-rule",
                                        "query": {
                                            "rule": "birthday",
                                            "operator": "contains",
                                            "operand": "Age Range",
                                            "value": [
                                                "25,34",
                                                "35,99"
                                            ]
                                        }
                                    }
                                ]
                            }
                        }
                    ]
                }
            }
        ]
    }
};


var aql = `
FOR item in customers
FILTER `
aql += parseItem(rules)
aql += `
LIMIT 100
RETURN item
`

function parseRule(item) {
    let column = item.query.rule
    let operator = item.query.operator
    let valueRule = item.query.value;
    if (operator === operatorConfig.contains) {
        if (column !== rulesConfig.birthday) {
            return containsNonBirthday(valueRule, column)
        } else {
            //birthday
            let listValues = item.query.value
            return birthday(listValues, column)
        }

    } else if (operator === operatorConfig.does_not_contain) {
        return doesNotContain(valueRule, column)
    }
}


function parseItem(item: any) {
    if (item.type == typeRuleConfig.query_builder_group) {
        let query = item.query
        // Đang gán logicalOperator ở ngoài child là OR.
        // Nhưng khi join mỗi lần nó lại lấy logicalOperator của child
        let logicalOperator = query.logicalOperator
        let result = query.children.map(function (child) {
            return parseItem(child)
        }).join(`\n ........ ${logicalOperator.toUpperCase()} \n`);
        return '(' + result + ')'
    }
    // type == query-builder-rule
    return parseRule(item)
}

function doesNotContain(list: Array<any>, column: string) {
    // Dùng NOT IN cũng được nhưng cách này dễ bóc tách data hơn.
    return `!POSITION(${JSON.stringify(list)}, item.${column})`
}
function containsNonBirthday(list: Array<any>, column: string) {
    // Tương đương IN [list]
    return `POSITION(${JSON.stringify(list)}, item.${column})`
}

function birthday(list: Array<string>, column: string) {
    let result = list.map((callback) => {
        let splitRange = callback.split(",");
        let parseRange = splitRange.map(str => parseInt(str, 10));
        return `(DATE_YEAR(DATE_NOW()) - DATE_YEAR(item.${column}) >= ${parseRange[0]} AND DATE_YEAR(DATE_NOW()) - DATE_YEAR(item.${column}) <= ${parseRange[1]})`
    }).join(` OR `)
    return `(${result})`
}

console.log('\x1b[32m', `${aql} `);
Editor is loading...
Leave a Comment