diff --git a/query-builder-elasticsearch.js b/query-builder-elasticsearch.js index 4fa3d08..792ff15 100644 --- a/query-builder-elasticsearch.js +++ b/query-builder-elasticsearch.js @@ -22,14 +22,26 @@ var QueryBuilder = $.fn.queryBuilder; // =============================== QueryBuilder.defaults({ ESBoolOperators: { + is_null: function(v){ return v; }, + is_not_null: function(v){ return v; }, + is_empty: function(v){ return v; }, + is_not_empty: function(v){ return v; }, equal: function(v){ return v; }, not_equal: function(v){ return v; }, + begins_with: function(v){ return v+'*'; }, + ends_with: function(v){ return '*'+v; }, + contains: function(v){ return '*'+v+'*'; }, + not_begins_with: function(v){ return v+'*'; }, + not_ends_with: function(v){ return '*'+v; }, + not_contains: function(v){ return '*'+v+'*'; }, less: function(v){ return {'lt': v}; }, less_or_equal: function(v){ return {'lte': v}; }, greater: function(v){ return {'gt': v}; }, greater_or_equal: function(v){ return {'gte': v}; }, between: function(v){ return {'gte': v[0], 'lte': v[1]}; }, - in : function(v){ return v.split(',').map(function(e) { return e.trim()}); } + not_between: function(v){ return {'gte': v[0], 'lte': v[1]}; }, + in : function(v){ return v.split(',').map(function(e) { return e.trim()}); }, + not_in : function(v){ return v.split(',').map(function(e) { return e.trim()}); } } }); @@ -65,51 +77,89 @@ QueryBuilder.extend({ if (this.hasOwnProperty(k)) { this[k].push(v) } else { this[k] = [v] } }; + var q_parts = {}; + q_parts.add = function (k, v) { + if (this.hasOwnProperty(k)) { this[k].push(v) } + else { this[k] = [v] } + }; - data.rules.forEach(function(rule) { - - function get_value(rule) { - if (rule.data && rule.data.hasOwnProperty('transform')) { - return window[rule.data.transform].call(this, rule.value); - } else { - return rule.value; - } + function get_value(rule) { + if (rule.data && rule.data.hasOwnProperty('transform')) { + return window[rule.data.transform].call(this, rule.value); + } else { + return rule.value; } + } - function make_query(rule) { - var mdb = that.settings.ESBoolOperators[rule.operator], - ope = that.getOperatorByType(rule.operator), - part = {}; - - if (mdb === undefined) { - error('Unknown elasticsearch operation for operator "{0}"', rule.operator); - } - - if (ope.nb_inputs !== 0) { - var es_key_val = {}; - es_key_val[rule.field] = mdb.call(that, get_value(rule)); - part[getQueryDSLWord(rule)] = es_key_val; - } + function make_query(rule) { + var mdb = that.settings.ESBoolOperators[rule.operator], + ope = that.getOperatorByType(rule.operator), + part = {}; - if (data.condition === 'OR' && rule.operator === 'not_equal') { - return {'bool': {'must_not': [part]}} - } else { - return part - } + if (mdb === undefined) { + error('Unknown elasticsearch operation for operator "{0}"', rule.operator); } - var clause = getClauseWord(data.condition, rule.operator); + var es_oper=getQueryDSLWord(rule) + var es_key_val = {}; + if (ope.nb_inputs !== 0) { + var ivalue=mdb.call(that, get_value(rule)); + es_key_val[rule.field] = ivalue + part[es_oper] = es_key_val; + } + if (rule.operator=='is_null' || rule.operator=='is_not_null' ){ + part[es_oper] = {'field': rule.field}; + } + if (rule.operator=='is_empty' || rule.operator=='is_not_empty' ){ + es_key_val[rule.field] = "" + part[es_oper] = es_key_val; + } - if (rule.rules && rule.rules.length>0) { - parts.add(clause, parse(rule)); + if (data.condition === 'OR' && not_operator(rule.operator)) { + return {'bool': {'must_not': [part]}} } else { - parts.add(clause, make_query(rule)); + return part } + } + + data.rules.forEach(function(rule) { + var clause = getClauseWord(data.condition, rule.operator); + var es_oper=getQueryDSLWord(rule) + if (es_oper==='wildcard'){ + if (rule.rules && rule.rules.length>0) { + q_parts.add(clause, parse(rule)); + } else { + q_parts.add(clause, make_query(rule)); + } + }else{ + if (rule.rules && rule.rules.length>0) { + parts.add(clause, parse(rule)); + } else { + parts.add(clause, make_query(rule)); + } + } }); + function isEmpty(obj) + { + for (var name in obj) + { + return false; + } + return true; + }; delete parts.add; - return {'bool': parts} + delete q_parts.add; + var result={} + if (!isEmpty(parts)){ + result['filter']={'bool': parts} + } + if (!isEmpty(q_parts)){ + result['query']={'bool': q_parts} + } + return result + }(data)); } }); @@ -126,6 +176,18 @@ function getQueryDSLWord(rule) { } } + if (rule.operator === 'begins_with' || rule.operator === 'ends_with' || rule.operator === 'contains' || + rule.operator === 'not_begins_with' || rule.operator === 'not_ends_with' || rule.operator === 'not_contains') { + return 'wildcard'; + } + + if (rule.operator === 'is_null' || rule.operator === 'is_not_null') { + return 'missing'; + } + if (rule.operator === 'is_empty' || rule.operator === 'is_not_empty') { + return 'term'; + } + if (rule.operator === 'in') { return 'terms'; } @@ -135,12 +197,20 @@ function getQueryDSLWord(rule) { } } -/** +function not_operator(operator) { + //return operator === 'not_equal'; + return (operator === 'not_equal'|| operator === 'not_begins_with' || + operator === 'not_ends_with' || operator === 'not_contains' || + operator === 'not_between' || operator === 'not_in' || + operator === 'is_not_null' || operator==='is_not_empty') +} + + /** * Get the right type of clause in the bool query */ function getClauseWord(condition, operator) { - if (condition === 'AND' && operator !== 'not_equal') { return 'must' } - if (condition === 'AND' && operator === 'not_equal') { return 'must_not' } + if (condition === 'AND' && !not_operator(operator)) { return 'must' } + if (condition === 'AND' && not_operator(operator)) { return 'must_not' } if (condition === 'OR') { return 'should' } }