Skip to content

Architecture Overview

William Shepherd edited this page May 7, 2018 · 8 revisions

From the start, lokijs has attempted to leverage familiarity with the mongo db api to create a fast, lightweight, in-memory database, with no library dependencies that can run and persist anywhere.

As Loki has evolved, it has kept and expanded on its core Mongo similarities while also augmenting that feature set with a versatile Fluent API interface for constructing queries, as well as a dynamic view interface for keeping live views of queries. Each of these interfaces work together to provide an interface which allows powerful and fast querying and transformation capabilities.

'Find' - Core Mongo capability

Lokijs currently implements following mongo functions with simplified options :

  • find()
  • findOne()
  • ensureIndex()
  • insert()
  • update()
  • delete()

Lokijs also currently implements the following find() operators :

  • $eq. $ne
  • $gt, $gte
  • $lt, $lte
  • $in
  • $contains
  • $regex
  • $and
  • $or

'Where' Filter functions

Lokijs also supports the use of javscript filter functions. These filter functions allow the user to cover complicated edge case queries which may not neatly fit into the mongo query structure. These 'where()' filters are not able to utilize any collection indexes and if applied to a DynamicView, they will not be serialized along with the database.

Loki Class structure :

Event Emitter

This allows internal and external notification of internal events. As actions are performed within the loki database, these events provide the means to monitor, manage or extend the functionality of these internal processes. Loki's Database, Collection, and DynamicView classes currently inherit and implement this Event Emitter functionality.

Database

The primary entry point for dealing with Lokijs, this class hosts all others and acts to create, manage, and serialize the database as a single entity.

Collection

This is the most important class in Loki, as it maintains all of the documents internally and provides a 'Core API' interface to those documents for querying and document management. Indexes are maintained, documents are added, updated and removed, meta info is generated, objects cloned, changes are optionally tracked, events established, and documents queried.

Resultset

This entity primarily establishes a 'state' for queries. Internally, this state is represented as a filtered set of indices to documents of a specific collection. Resulsets allow mixing mongo filters with filter functions, allowing sorting, limit/offset, query branching, map/reduce, and bulk removal capabilities. The 'result' of this is the capability to establish complicated query and transformation pipelines.

DynamicView

What the Resultset lacks is its dependence on static database state. Resultset is meant to perform instant action to obtain results or modify the database within the context of its current state. The DynamicView class attempts to allow query pipelines to remain up-to-date as documents are added, updated, and removed. By default, its internal resultset will be kept up to date (index set)... if you choose a persistent option during creation, it will keep the actual documents in an internal document array set.

Persistence Adapters

Loki natively supports filesystem and localStorage within its primary loki.js source file. To support other storage mechanisms we have created a simple persistence adapter interface. Loki provides an indexedDB adapter (lokiIndexedAdapter.js) which implements this adapter interface but adapters can be written for a wide variety of storage methods. Since LokiJS is an in-memory database, it lends itself most to key/value database stores. This interface may be expanded upon in the future for more granular database or collection level access.

Autosave Timer

An option exists for you to pass into the loki constructor, to perform automatic, periodic database saves (provided changes are pending). This timer may evolve into a scheduler for other tasks in the future.