askjs icon indicating copy to clipboard operation
askjs copied to clipboard

Perform mongo queries on regular JS objects.

ask.js

Perform mongo queries on regular JS objects.

Compatibility

ask.js is compatible with the ECMAScript 5.1 standard, for retrocompatibility take advantage of modernizr and polyfills.

Tests have been passed for both latest Chrome and Firefox 15.0.1.

How to use?

Add ask.js to your page and use ask.mongify() method to convert an array into a mongified collection. ;)

var collection = [
  {"city": "ACMAR", "loc": [-86.51557, 33.584132], "pop": 6055, "state": "AL", "_id": "35004"},
  {"city": "ADAMSVILLE", "loc": [-86.959727, 33.588437], "pop": 10616, "state": "AL", "_id": "35005"},
  {"city": "NINILCHIK", "loc": [-151.639604, 60.010833], "pop": 767, "state": "AK", "_id": "99639"},
  {"city": "NONDALTON", "loc": [-154.731675, 60.030837], "pop": 233, "state": "AK", "_id": "99640"},
  {"city": "LAKESIDE", "loc": [-109.986878, 34.166224], "pop": 5350, "state": "AZ", "_id": "85929"},
  {"city": "PINETOP", "loc": [-109.919668, 34.117459], "pop": 1938, "state": "AZ", "_id": "85935"}
];
ask.mongify(collection); // it returns the same collection object

collection.find( { "state": "AK" } );

Features supported

Dot notation & subobjects

All stuff related to dot notation, $elemMatch and subobjects is supported according to Mongo specification.

You can find [more information in Mongo documentation](http://www.mongodb.org/display/DOCS/Dot+Notation+(Reaching+into+Objects).

JavaScript expressions and $where clause

You can use JavaScript expressions and the $where clause as it is described in Mongo documentation about $where

Regular expressions

You can use JavaScript regular expressions literals or $regex constructor to match agains a regular expression. See more about regular expresssions in Mongo documentation.

Operators

At the moment, almost all operators are supported but no indexation is applied on any search:

Notes related to $type operator

ask.js provides solid support for types 1 (double), 2 (string), 3 (object), 4 (array), 8 (boolean), 9 (date), 10 (null), 11 (regular expression), 13 (JavaScript code), 15 (JavaScript code with scope), 16 (32-bit integer), 18 (64-bit ~ 53-bit integer)

As this is only JavaScript, it does not use BSON but JSON and some BSON data types are missed, see the commentaries below to further details.

  • Type 1: double - in JavaScript, any number is a double, so this matches any field which type is number (I mean, typeof returns number)
  • Type 3: object - but only if this object is not null neither one of these sub-objects: Array, Date RegExp
  • Type 5: binary data - is not supported (yet). You may ask how to support this feature. I don't know yet but, from my experience, I know there are methods to convert BSON into JSON, let me try...
  • Type 7: object id - is not supported (yet). Same here.
  • Types 13 and 15: JavaScript code and JavaScript code with scope - they are treated like looking for Function instances.
  • Type 14: symbol - This type refers to Ruby symbols which are different from strings. It is not supported (yet). Same reasons.
  • Type 16: 32-bit integers - JavaScript has no an integer type. But it can represent up to two times 2^52 integer values, half positive and halft negative using double types. So, using type 16 only test for an integer v that 2^32 < v < -2^32.
  • Type 17: timestamp - is not supported (yet). Same here.
  • Type 18: 64-bit integers - Same reasons here allow us to check if there is an integer inside a double and nothing more. But those integers have are 52-bit sized so, this test for an integer v that 2^52 < v < -2^52.
  • Type 255 / -1: min key - is not supported (yet). Reasons are difficult to explain right now.
  • Type 127: max key - is not supported (yet). Same as above.

As optional, if you feel uncomfortable with the current implementation or know how to test for some of the missed types or you created your own types, you can use ask.types() package method to set an alternative implementation. Call ask.types() as in the following example:

ask.types({
// This disable support for 64-bit integers
'18': false,

// This overrides the test for object returning true for every value instance of Object
'3': function (value) {
  return value instanceof Object;
},

// This enables support for object id
'7': function (value) {
  return value.$objectId !== undefined;
}

// This add support for a custom type -4: weak array-like object
'-4': function (value) {
  return typeof value.length === 'number' &&
         parseInt(value.length) === parseFloat(value.length) &&
         value.length >= 0;
}
});

// This reset type tests to default ones
ask.types();