docs: function checkJSONExpression(expression, json) {
    if (! (expression && json)) {
      return false;
    }
  
    // array expressions never match non-arrays or arrays of a different length.
    if (_.isArray(expression) && !(_.isArray(json) && expression.length === json.length)) {
      return false;
    }
  
    return _.all(expression, function(v, k) {
  
      // check "$" properties
      if (k === "$not") return (! checkJSONExpression(v, json));
      if (k === "$unordered") {
        return v.length === json.length && arrayContains(json, v);
      }
      if (k === "$contains") {
        return arrayContains(json, v);
      }
      if (k === "$length" ) return(v === json.length);
      if (k === "$gt") return (json > v);
      if (k === "$gte") return (json >= v);
      if (k === "$lt") return (json < v);
      if (k === "$lte") return (json <= v);
  
      // check $not-exists
      if (! _.has(json, k)) return (v === "$not-exists");
  
      // check rest of "$" values.
      if (v === "$exists") return _.has(json, k);
      if (v === "$string") return _.isString(json[k]);
      if (_.isRegExp(v)) return v.test(json[k]);
      if (_.isObject(v)) return checkJSONExpression(v, json[k]);
      if (v === "$date") {
        try {
          new Date(json[k]);
          return true;
        } catch (e) {
          return false;
        }
      }
      if (v === "$int") {
        //http://stackoverflow.com/questions/3885817/how-to-check-if-a-number-is-float-or-integer
        return (typeof json[k] === 'number' && json[k] % 1 === 0);
      }
  
      // check a strict equals
      return (v === json[k]);
    });
  }