AWESOME FEATURES AND MODERN API

ForerunnerDB is the only JavaScript database with a simple, rich JSON-based query language. Based on MongoDB’s query language and built with web applications in mind, ForerunnerDB will have you up and running in minutes.

Web database

Persistent storage across page loads, built-in basic and compound index support, easy JSON-based query language

Open-source

You can download, contribute and participate in the development of ForerunnerDB on GitHub

Developer-friendly

Cut down development time and project complexity with automatic data-binding and advanced views

Event hooks for your app

Listen for changes to data, react to document and view updates, create interactive data views

Browser-storage friendly

Works with browser storage to persist data as required by your application, falls back from IndexedDB -> WebSQL -> LocalStorage

Data-intensive applications

Build highly complex data-intensive applications by utilising a battle-tested production-ready web database

What is ForerunnerDB

ForerunnerDB is a NoSQL JavaScript JSON database with a query language based on MongoDB (with some differences) and runs on browsers and Node.js. It is in use in many large production web applications and is transparently used by over 6 million clients. ForerunnerDB is the most advanced, battle-tested and production ready browser-based JSON database system available today.

What is ForerunnerDB’s Primary Use Case?

ForerunnerDB was created primarily to allow web (and mobile web / hybrid) application developers to easily store, query and manipulate JSON data in the browser / mobile app via a simple query language, making handling JSON data significantly easier.

ForerunnerDB supports data persistence on both the client (via LocalForage) and in Node.js (by saving and loading JSON data files).

If you build advanced web applications with AngularJS or perhaps your own framework or if you are looking to build a server application / API that needs a fast queryable in-memory store with file-based data persistence and a very easy setup (simple installation via NPM and no requirements except Node.js) you will also find ForerunnerDB very useful.

An example hybrid application that runs on iOS, Android and Windows Mobile via Ionic (AngularJS + Cordova with some nice extensions) is available in this repository under the ionicExampleClient folder. See here for more details.

Download

NPM

If you are using Node.js (or have it installed) you can use NPM to download ForerunnerDB via:

npm install forerunnerdb

NPM Dev Builds

You can also install the development version which usually includes new features that are considered either unstable or untested. To install the development version you can ask NPM for the dev tag:

npm install forerunnerdb --tag dev

Bower

You can also install ForerunnerDB via the bower package manager:

bower install forerunnerdb

No Package Manager

If you are still a package manager hold-out or you would prefer a more traditional download, please click here.

How to Use

Use ForerunnerDB in Browser

fdb-all.min.js is the entire ForerunnerDB with all the added extras. If you prefer only the core database functionality (just collections, no views etc) you can use fdb-core.min.js instead. A list of the different builds is available for you to select the best build for your purposes.

Include the fdb-all.min.js file in your HTML (change path to the location you put forerunner):

<script src="./js/dist/fdb-all.min.js" type="text/javascript"></script>

Use ForerunnerDB in Node.js

After installing via npm (see above) you can require ForerunnerDB in your code:

var ForerunnerDB = require("forerunnerdb");
var fdb = new ForerunnerDB();

Create a Database

var db = fdb.db("myDatabaseName");

If you do not specify a database name a randomly generated one is provided instead.

Collections (Tables)

Data Binding: Enabled

To create or get a reference to a collection object, call db.collection (where collectionName is the name of your collection):

var collection = db.collection("collectionName");

In our examples we will use a collection called “item" which will store some fictitious items for sale:

var itemCollection = db.collection("item");

Auto-Creation

When you request a collection that does not yet exist it is automatically created. If it already exists you are given the reference to the existing collection. If you want ForerunnerDB to throw an error if a collection is requested that does not already exist you can pass an option to the collection() method instead:

var collection = db.collection("collectionName", {autoCreate: false});

Specifying a Primary Key Up-Front

If no primary key is specified ForerunnerDB uses “_id" by default.

On requesting a collection you can specify a primary key that the collection should be using. For instance to use a property called “name" as the primary key field:

var collection = db.collection("collectionName", {primaryKey: "name"});

You can also read or specify a primary key after instantiation via the primaryKey() method.

Capped Collections

Occasionally it is useful to create a collection that will store a finite number of records. When that number is reached, any further documents inserted into the collection will cause the oldest inserted document to be removed from the collection on a first-in-first-out rule (FIFO).

In this example we create a capped collection with a document limit of 5:

var collection = db.collection("collectionName", {capped: true, size: 5});

Inserting Documents

If you do not specify a value for the primary key, one will be automatically generated for any documents inserted into a collection. Auto-generated primary keys are pseudo-random 16 character strings.

PLEASE NOTE: When doing an insert into a collection, ForerunnerDB will automatically split the insert up into smaller chunks (usually of 100 documents) at a time to ensure the main processing thread remains unblocked. If you wish to be informed when the insert operation is complete you can pass a callback method to the insert call. Alternatively you can turn off this behaviour by calling yourCollection.deferredCalls(false);

You can either insert a single document object:

itemCollection.insert({
	_id: 3,
	price: 400,
	name: "Fish Bones"
});

or pass an array of documents:

itemCollection.insert([{
	_id: 4,
	price: 267,
	name:"Scooby Snacks"
}, {
	_id: 5,
	price: 234,
	name: "Chicken Yum Yum"
}]);

Inserting a Large Number of Documents

When inserting large amounts of documents ForerunnerDB may break your insert operation into multiple smaller operations (usually of 100 documents at a time) in order to avoid blocking the main processing thread of your browser / Node.js application. You can find out when an insert has completed either by passing a callback to the insert call or by switching off async behaviour.

Passing a callback:

itemCollection.insert([{
	_id: 4,
	price: 267,
	name:"Scooby Snacks"
}, {
	_id: 5,
	price: 234,
	name: "Chicken Yum Yum"
}], function (result) {
	// The result object will contain two arrays (inserted and failed)
	// which represent the documents that did get inserted and those
	// that didn't for some reason (usually index violation). Failed
	// items also contain a reason. Inspect the failed array for further
	// information.
});

If you wish to switch off async behaviour you can do so on a per-collection basis via:

db.collection('myCollectionName').deferredCalls(false);

After async behaviour (deferred calls) has been disabled, you can insert records and be sure that they will all have inserted before the next statement is processed by the application’s main thread.

Inserting Special Objects

JSON has limitations on the types of objects it will serialise and de-serialise back to an object. Two very good examples of this are the Date() and RegExp() objects. Both can be serialised via JSON.stringify() but when calling JSON.parse() on the serialised version neither type will be “re-materialised" back to their object representations.

For example:

var a = {
	dt: new Date()
};

a.dt instanceof Date; // true

var b = JSON.stringify(a); // "{"dt":"2016-02-11T09:52:49.170Z"}"

var c = JSON.parse(b); // {dt: "2016-02-11T09:52:49.170Z"}

c.dt instanceof Date; // false

As you can see, parsing the JSON string works but the dt key no longer contains a Date instance and only holds the string representation of the date. This is a fundamental drawback of using JSON.stringify() and JSON.parse() in their native form.

If you want ForerunnerDB to serialise / de-serialise your object instances you must use this format instead:

var a = {
	dt: fdb.make(new Date())
};

By wrapping the new Date() in fdb.make() we allow ForerunnerDB to provide the Date() object with a custom .toJSON() method that serialises it differently to the native implementation.

For convenience the make() method is also available on all ForerunnerDB class instances e.g. db, collection, view etc. For instance you can access make via:

var fdb = new ForerunnerDB(),
	db = fdb.db('test'),
	coll = db.collection('testCollection'),
	date = new Date();

// All of these calls will do the same thing:
date = fdb.make(date);
date = db.make(date);
date = coll.make(date);

You can read more about how ForerunnerDB’s serialiser works here.

Supported Instance Types and Usage
Date
var a = {
	dt: fdb.make(new Date())
};
RegExp
var a = {
	re: fdb.make(new RegExp(".*", "i"))
};

or

var a = {
	re: fdb.make(/.*/i))
};
Adding Custom Types to the Serialiser

ForerunnerDB’s serialisation system allows for custom type handling so that you can expand JSON serialisation to your own custom class instances.

This can be a complex topic so it has been broken out into the Wiki section for further reading here.

Searching the Collection

PLEASE NOTE While we have tried to remain as close to MongoDB’s query language as possible, small differences are present in the query matching logic. The main difference is described here: Find behaves differently from MongoDB

See the Special Considerations section for details about how names of keys / properties in a query object can affect a query’s operation.

Much like MongoDB, searching for data in a collection is done using the find() method, which supports many of the same operators starting with a $ that MongoDB supports. For instance, finding documents in the collection where the price is greater than 90 but less than 150, would look like this:

itemCollection.find({
	price: {
		"$gt": 90,
		"$lt": 150
	}
});

And would return an array with all matching documents. If no documents match your search, an empty array is returned.

Regular Expressions

Searches support regular expressions for advanced text-based queries. Simply pass the regular expression object as the value for the key you wish to search, just like when using regular expressions with MongoDB.

Insert a document:

collection.insert([{
	"foo": "hello"
}]);

Search by regular expression:

collection.find({
	"foo": /el/
});

You can also use the RegExp object instead:

var myRegExp = new RegExp("el");

collection.find({
	"foo": myRegExp
});

Query Operators

ForerunnerDB supports many of the same query operators that MongoDB does, and adds some that are not available in MongoDB but which can help in browser-centric applications.

  • $gt Greater Than
  • $gte Greater Than / Equal To
  • $lt Less Than
  • $lte Less Than / Equal To
  • $eq Equal To (==)
  • $eeq Strict Equal To (===)
  • $ne Not Equal To (!=)
  • $nee Strict Not Equal To (!==)
  • $in Match Any Value In An Array Of Values
  • $fastIn Match Any String or Number In An Array Of String or Numbers
  • $nin Match Any Value Not In An Array Of Values
  • $distinct Match By Distinct Key/Value Pairs
  • $count Match By Length Of Sub-Document Array
  • $or Match any of the conditions inside the sub-query
  • $and Match all conditions inside the sub-query
  • $exists Check that a key exists in the document
  • $elemMatch Limit sub-array documents by query
  • $elemsMatch Multiple document version of $elemMatch
  • $aggregate Converts an array of documents into an array of values base on a path / key
  • $near Geospatial operation finds outward from a central point
$gt

Selects those documents where the value of the field is greater than (i.e. >) the specified value.

{ field: {$gt: value} }
Usage
var fdb = new ForerunnerDB(),
	db = fdb.db("test"),
	coll = db.collection("test");
	
coll.insert([{
	_id: 1,
	val: 1
}, {
	_id: 2,
	val: 2
}, {
	_id: 3,
	val: 3
}]);

result = coll.find({
	val: {
		$gt: 1
	}
});

Result is:

[{
	_id: 2,
	val: 2
}, {
	_id: 3,
	val: 3
}]
$gte

Selects the documents where the value of the field is greater than or equal to (i.e. >=) the specified value.

{ field: {$gte: value} }
Usage
var fdb = new ForerunnerDB(),
	db = fdb.db("test"),
	coll = db.collection("test");
	
coll.insert([{
	_id: 1,
	val: 1
}, {
	_id: 2,
	val: 2
}, {
	_id: 3,
	val: 3
}]);

result = coll.find({
	val: {
		$gte: 1
	}
});

Result is:

[{
	_id: 1,
	val: 1
}, {
	_id: 2,
	val: 2
}, {
	_id: 3,
	val: 3
}]
$lt

Selects the documents where the value of the field is less than (i.e. <) the specified value. [/kc_column_text][kc_raw_code code="PHByZT48Y29kZSBjbGFzcz0ibGFuZ3VhZ2UtamF2YXNjcmlwdCI+eyBmaWVsZDogeyAkbHQ6IHZhbHVlfSB9PC9jb2RlPjwvcHJlPg==" _id="246566"][kc_column_text _id="122167"]

Usage
var fdb = new ForerunnerDB(),
	db = fdb.db("test"),
	coll = db.collection("test");
	
coll.insert([{
	_id: 1,
	val: 1
}, {
	_id: 2,
	val: 2
}, {
	_id: 3,
	val: 3
}]);

result = coll.find({
	val: {
		$lt: 2
	}
});

Result is:

[{
	_id: 1,
	val: 1
}]
$lte

Selects the documents where the value of the field is less than or equal to (i.e. <=) the specified value. [/kc_column_text][kc_raw_code code="PHByZT48Y29kZSBjbGFzcz0ibGFuZ3VhZ2UtamF2YXNjcmlwdCI+eyBmaWVsZDogeyAkbHRlOiB2YWx1ZX0gfTwvY29kZT48L3ByZT4=" _id="639094"][kc_column_text _id="581885"]

Usage
var fdb = new ForerunnerDB(),
	db = fdb.db("test"),
	coll = db.collection("test");
	
coll.insert([{
	_id: 1,
	val: 1
}, {
	_id: 2,
	val: 2
}, {
	_id: 3,
	val: 3
}]);

result = coll.find({
	val: {
		$lte: 2
	}
});

Result is:

[{
	_id: 1,
	val: 1
}, {
	_id: 2,
	val: 2
}]
$eq

Selects the documents where the value of the field is equal (i.e. ==) to the specified value.

{field: {$eq: value} }
Usage
var fdb = new ForerunnerDB(),
	db = fdb.db("test"),
	coll = db.collection("test");
	
coll.insert([{
	_id: 1,
	val: 1
}, {
	_id: 2,
	val: 2
}, {
	_id: 3,
	val: 3
}]);

result = coll.find({
	val: {
		$eq: 2
	}
});

Result is:

[{
	_id: 2,
	val: 2
}]
$eeq

Selects the documents where the value of the field is strict equal (i.e. ===) to the specified value. This allows for strict equality checks for instance zero will not be seen as false because 0 !== false and comparing a string with a number of the same value will also return false e.g. (‘2’ == 2) is true but (‘2’ === 2) is false.

{field: {$eeq: value} }
Usage
var fdb = new ForerunnerDB(),
	db = fdb.db("test"),
	coll = db.collection("test");
	
coll.insert([{
	_id: 1,
	val: "2"
}, {
	_id: 2,
	val: 2
}, {
	_id: 3,
	val: "2"
}]);

result = coll.find({
	val: {
		$eeq: 2
	}
});

Result is:

[{
	_id: 2,
	val: 2
}]
$ne

Selects the documents where the value of the field is not equal (i.e. !=) to the specified value. This includes documents that do not contain the field.

{field: {$ne: value} }
Usage
var fdb = new ForerunnerDB(),
	db = fdb.db("test"),
	coll = db.collection("test");
	
coll.insert([{
	_id: 1,
	val: 1
}, {
	_id: 2,
	val: 2
}, {
	_id: 3,
	val: 3
}]);

result = coll.find({
	val: {
		$ne: 2
	}
});

Result is:

[{
	_id: 1,
	val: 1
}, {
	_id: 3,
	val: 3
}]
$nee

Selects the documents where the value of the field is not equal equal (i.e. !==) to the specified value. This allows for strict equality checks for instance zero will not be seen as false because 0 !== false and comparing a string with a number of the same value will also return false e.g. (‘2’ != 2) is false but (‘2’ !== 2) is true. This includes documents that do not contain the field.

{field: {$nee: value} }
Usage
var fdb = new ForerunnerDB(),
	db = fdb.db("test"),
	coll = db.collection("test");
	
coll.insert([{
	_id: 1,
	val: 1
}, {
	_id: 2,
	val: 2
}, {
	_id: 3,
	val: 3
}]);

result = coll.find({
	val: {
		$nee: 2
	}
});

Result is:

[{
	_id: 1,
	val: 1
}, {
	_id: 3,
	val: 3
}]
$in

If your field is a string or number and your array of values are also either strings or numbers you can utilise $fastIn which is an optimised $in query that uses indexOf() to identify matching values instead of looping over all items in the array of values and running a new matching process against each one. If your array of values include sub-queries or other complex logic you should use $in, not $fastIn.

Selects documents where the value of a field equals any value in the specified array.

{ field: { $in: [, , ...  ] } }
Usage
var fdb = new ForerunnerDB(),
	db = fdb.db("test"),
	coll = db.collection("test");
	
coll.insert([{
	_id: 1,
	val: 1
}, {
	_id: 2,
	val: 2
}, {
	_id: 3,
	val: 3
}]);

result = coll.find({
	val: {
		$in: [1, 3]
	}
});

Result is:

[{
	_id: 1,
	val: 1
}, {
	_id: 3,
	val: 3
}]
$fastIn

You can use $fastIn instead of $in when your field contains a string or number and your array of values contains only strings or numbers. $fastIn utilises indexOf() to speed up performance of the query. This means that the array of values is not evaluated for sub-queries, other operators like $gt etc, and it is assumed that the array of values is a completely flat array, filled only with strings or numbers.

Selects documents where the string or number value of a field equals any string or number value in the specified array.

The array of values MUST be a flat array and contain only strings or numbers.

{ field: { $fastIn: [, , ...  ] } }
Usage
var fdb = new ForerunnerDB(),
	db = fdb.db("test"),
	coll = db.collection("test");
	
coll.insert([{
	_id: 1,
	val: 1
}, {
	_id: 2,
	val: 2
}, {
	_id: 3,
	val: 3
}]);

result = coll.find({
	val: {
		$fastIn: [1, 3]
	}
});

Result is:

[{
	_id: 1,
	val: 1
}, {
	_id: 3,
	val: 3
}]
$nin

Selects documents where the value of a field does not equal any value in the specified array.

{ field: { $nin: [ ,  ...  ]} }
Usage
var fdb = new ForerunnerDB(),
	db = fdb.db("test"),
	coll = db.collection("test");
	
coll.insert([{
	_id: 1,
	val: 1
}, {
	_id: 2,
	val: 2
}, {
	_id: 3,
	val: 3
}]);

result = coll.find({
	val: {
		$nin: [1, 3]
	}
});

Result is:

[{
	_id: 2,
	val: 2
}]
$distinct

Selects the first document matching a value of the specified field. If any further documents have the same value for the specified field they will not be returned.

{ $distinct: { field: 1 } }
Usage
var fdb = new ForerunnerDB(),
	db = fdb.db("test"),
	coll = db.collection("test");
	
coll.insert([{
	_id: 1,
	val: 1
}, {
	_id: 2,
	val: 1
}, {
	_id: 3,
	val: 1
}, {
	_id: 4,
	val: 2
}]);

result = coll.find({
	$distinct: {
		val: 1
	}
});

Result is:

[{
	_id: 1,
	val: 1
}, {
	_id: 4,
	val: 2
}]
$count

Version >= 1.3.326

This is equivalent to MongoDB’s $size operator but please see below for usage.

Selects documents based on the length (count) of items in an array inside a document.

{ $count: { field:  } }
Select Documents Where The “arr" Array Field Has Only 1 Item
var fdb = new ForerunnerDB(),
	db = fdb.db("test"),
	coll = db.collection("test");
	
coll.insert([{
	_id: 1,
	arr: []
}, {
	_id: 2,
	arr: [{
		val: 1		
	}]
}, {
	_id: 3,
	arr: [{
		val: 1
	}, {
		val: 2		
	}]
}]);

result = coll.find({
	$count: {
		arr: 1
	}
});

Result is:

[{
	_id: 2,
	arr: [{
		val: 1		
	}]
}]
Select Documents Where The “arr" Array Field Has More Than 1 Item
var fdb = new ForerunnerDB(),
	db = fdb.db("test"),
	coll = db.collection("test");
	
coll.insert([{
	_id: 1,
	arr: []
}, {
	_id: 2,
	arr: [{
		val: 1		
	}]
}, {
	_id: 3,
	arr: [{
		val: 1
	}, {
		val: 2		
	}]
}]);

result = coll.find({
	$count: {
		arr: {
			$gt: 1
		}
	}
});

Result is:

[{
	_id: 3,
	arr: [{
		val: 1
	}, {
		val: 2		
	}]
}]
$or

The $or operator performs a logical OR operation on an array of two or more and selects the documents that satisfy at least one of the .

{ $or: [ {  }, {  }, ... , {  } ] }
Usage
var fdb = new ForerunnerDB(),
	db = fdb.db("test"),
	coll = db.collection("test");
	
coll.insert([{
	_id: 1,
	val: 1
}, {
	_id: 2,
	val: 2
}, {
	_id: 3,
	val: 3
}]);

result = coll.find({
	$or: [{
		val: 1
	}, {
		val: {
			$gte: 3 
		}
	}]
});

Result is:

[{
	_id: 1,
	val: 1
}, {
	_id: 3,
	val: 3
}]
$and

Performs a logical AND operation on an array of two or more expressions (e.g. , , etc.) and selects the documents that satisfy all the expressions in the array. The $and operator uses short-circuit evaluation. If the first expression (e.g. ) evaluates to false, ForerunnerDB will not evaluate the remaining expressions.

{ $and: [ {  }, {  } , ... , {  } ] }
Usage
var fdb = new ForerunnerDB(),
	db = fdb.db("test"),
	coll = db.collection("test");
	
coll.insert([{
	_id: 1,
	val: 1
}, {
	_id: 2,
	val: 2
}, {
	_id: 3,
	val: 3
}]);

result = coll.find({
	$and: [{
		_id: 3
	}, {
		val: {
			$gte: 3 
		}
	}]
});

Result is:

[{
	_id: 3,
	val: 3
}]
$exists

When is true, $exists matches the documents that contain the field, including documents where the field value is null. If is false, the query returns only the documents that do not contain the field.

{ field: { $exists:  } }
Usage
var fdb = new ForerunnerDB(),
	db = fdb.db("test"),
	coll = db.collection("test");
	
coll.insert([{
	_id: 1,
	val: 1
}, {
	_id: 2,
	val: 2,
	moo: "hello"
}, {
	_id: 3,
	val: 3
}]);

result = coll.find({
	moo: {
		$exists: true
	}
});

Result is:

[{
	_id: 2,
	val: 2,
	moo: "hello"
}]

Projection

$elemMatch

The $elemMatch operator limits the contents of an array field from the query results to contain only the first element matching the $elemMatch condition.

The $elemMatch operator is specified in the options object of the find call rather than the query object.

MongoDB $elemMatch Documentation

Usage
var fdb = new ForerunnerDB(),
	db = fdb.db("test"),
	coll = db.collection("test");
	
coll.insert({
	names: [{
		_id: 1,
		text: "Jim"
	}, {
		_id: 2,
		text: "Bob"
	}, {
		_id: 3,
		text: "Bob"
	}, {
		_id: 4,
		text: "Anne"
	}, {
		_id: 5,
		text: "Simon"
	}, {
		_id: 6,
		text: "Uber"
	}]
});

result = coll.find({}, {
	$elemMatch: {
		names: {
			text: "Bob"
		}
	}
});

Result is:

{
	names: [{
		_id: 2,
		text: "Bob"
	}]
}

Notice that only the FIRST item matching the $elemMatch clause is returned in the names array. If you require multiple matches use the ForerunnerDB-specific $elemsMatch operator instead.

$elemsMatch

The $elemsMatch operator limits the contents of an array field from the query results to contain only the elements matching the $elemMatch condition.

The $elemsMatch operator is specified in the options object of the find call rather than the query object.

Usage
var fdb = new ForerunnerDB(),
	db = fdb.db("test"),
	coll = db.collection("test");
	
coll.insert({
	names: [{
		_id: 1,
		text: "Jim"
	}, {
		_id: 2,
		text: "Bob"
	}, {
		_id: 3,
		text: "Bob"
	}, {
		_id: 4,
		text: "Anne"
	}, {
		_id: 5,
		text: "Simon"
	}, {
		_id: 6,
		text: "Uber"
	}]
});

result = coll.find({}, {
	$elemsMatch: {
		names: {
			text: "Bob"
		}
	}
});

Result is:

{
	names: [{
		_id: 2,
		text: "Bob"
	}, {
		_id: 3,
		text: "Bob"
	}]
}

Notice that all items matching the $elemsMatch clause are returned in the names array. If you require match on ONLY the first item use the MongoDB-compliant $elemMatch operator instead.

$aggregate

Coverts an array of documents into an array of values that are derived from a key or path in the documents. This is very useful when combined with the $find operator to run sub-queries and return arrays of values from the results.

{ $aggregate: path}
Usage
var fdb = new ForerunnerDB(),
	db = fdb.db("test"),
	coll = db.collection("test");
	
coll.insert([{
	_id: 1,
	val: 1
}, {
	_id: 2,
	val: 2
}, {
	_id: 3,
	val: 3
}]);

result = coll.find({}, {
	$aggregate: "val"
});

Result is:

[1, 2, 3]
$near

PLEASE NOTE: BETA STATUS – PASSES UNIT TESTING BUT MAY BE UNSTABLE

Finds other documents whose co-ordinates based on a 2d index are within the specified distance from the specified centre point. Co-ordinates must be presented in latitude / longitude for $near to work.

{
	field: {
		$near: {
			$point: [<latitude number>, <longitude number>],
			$maxDistance: <number>,
			$distanceUnits: <units string>
		}
	}
}
Usage
var fdb = new ForerunnerDB(),
	db = fdb.db("test"),
	coll = db.collection("test");

coll.insert([{
	latLng: [51.50722, -0.12750],
	name: 'Central London'
}, {
	latLng: [51.525745, -0.167550], // 2.18 miles
	name: 'Marylebone, London'
}, {
	latLng: [51.576981, -0.335091], // 10.54 miles
	name: 'Harrow, London'
}, {
	latLng: [51.769451, 0.086509], // 20.33 miles
	name: 'Harlow, Essex'
}]);

// Create a 2d index on the lngLat field
coll.ensureIndex({
	latLng: 1
}, {
	type: '2d'
});

// Query index by distance
// $near queries are sorted by distance from centre point by default
result = coll.find({
	latLng: {
		$near: {
			$point: [51.50722, -0.12750],
			$maxDistance: 3,
			$distanceUnits: 'miles'
		}
	}
});

Result is:

[{
	"lngLat": [51.50722, -0.1275],
	"name": "Central London",
	"_id": "1f56c0b5885de40"
}, {
	"lngLat": [51.525745, -0.16755],
	"name": "Marylebone, London",
	"_id": "372a34d9f17fbe0"
}]

Download/Documentation: https://github.com/ForerunnerDB/


Leave a Reply

Your email address will not be published. Required fields are marked *