diff --git a/README.md b/README.md
index 00876ad..57ea540 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,3135 @@
-# contexture-docs
-Documentation for Contexture
+This is the complete documentation for [Contexture](https://github.com/smartprocure/contexture).
+
+## About Contexture
+### What is Contexture
+People of the Internet, here we officialy introduce you to
+`contexture`, our framework for building search interfaces.
+
+This framework is carefully designed to be a generic solution for a
+universe of unlimited possible search interfaces. We've started with a
+minimal set of repositories that are representative of tools that
+empower our business, but are intended to be merely examples. If
+anything, our approaches are only use cases, for the potential of
+this tool is ultimately yours to take.
+
+A quick search over the Internet would reveal that the word
+`contexture` means: `the fact or manner of being woven or linked
+together to form a connected whole` and also `the putting together of
+words and sentences in connected composition; the construction of a
+text`.
+
+Picking `contexture` as the name for this project means that we are
+trying to expose not only our ultimate intentions, but also more or
+less how the system is built. The way our projects work is by a DSL
+that is used to gather different intended search inputs, each one
+representing some useful abstraction of a search filter (like an input
+where you can write a word to be searched, or another where you can
+filter the search results by one or more options), then using the
+values to process a DSL that will end up retrieving values from one or
+more different databases, then returning these values on the
+respective sections of the DSL, so that each result can update each
+one of the components of the user interface. A more detailed
+description is visible in the following diagram.
+
+
+
+The canonical example of a Contexture Node is faceted search, where
+you have a checkbox list that is both a filter (in the sense that it
+restricts results based on the checked values) and an aggregation
+(which shows the top n values that can be checked). Contexture allows
+them to be nested in advanced searches with boolean joins like
+`and`/`or`/`not`.
+
+
+
+This thought process will become more clear as we progress through the
+docs. Hopefully, some pages later it will be easy to grasp how we
+provide a new perspective on building search interfaces, and perhaps
+even how you can use it to power up your business, just like we have
+been doing for almost a decade.
+
+### Glossary of Terms
+#### Contexture
+
+NOUN
+
+1. The fact or manner of being woven or linked together to form a
+connected whole.
+1.1. A mass of things interwoven together; a fabric.
+1.2. The putting together of words and sentences in connected
+composition; the construct of a text.
+1.3. A connected literary structure; a continuous text.
+
+[Source](https://en.oxforddictionaries.com/definition/us/contexture).
+
+#### Domain-Specific Language (DSL)
+
+A domain-specific language (DSL) is a computer language specialized
+to a particular application domain. This is in contrast to a
+general-purpose language (GPL), which is broadly applicable across
+domains.
+
+[Source](https://en.wikipedia.org/wiki/Domain-specific_language).
+
+#### Search Query
+
+According to Wikipedia, `Search Query`, in the context of the `web`, refers to:
+
+...a query that a user enters into a web search engine to satisfy his or her
+information needs. Web search queries are distinctive in that they are often
+plain text or hypertext with optional search-directives (such as "and"/"or"
+with "-" to exclude). They vary greatly from standard query languages, which
+are governed by strict syntax rules as command languages with keyword or
+positional parameters.
+
+[Source](https://en.wikipedia.org/wiki/Web_search_query).
+
+#### Faceted Search
+
+Faceted search, also known as faceted navigation or faceted browsing, is a
+technique used by eCommerce brands to help users analyze, organize, and
+filter large sets of product inventory based on filters such as size, color,
+price, and brand.
+
+[Source](https://www.dynamicyield.com/glossary/faceted-search/).
+
+Faceted search, also called faceted navigation or faceted browsing, is a
+technique for accessing information organized according to a faceted
+classification system, allowing users to explore a collection of information
+by applying multiple filters. A faceted classification system classifies each
+information element along multiple explicit dimensions, called facets,
+enabling the classifications to be accessed and ordered in multiple ways
+rather than in a single, pre-determined, taxonomic order.
+
+[Source](https://en.wikipedia.org/wiki/Faceted_search).
+
+#### Search Filter
+
+An extension of faceted search, a search filter is a specific product
+attribute a visitor can use to refine the search results of a particular
+category listing, e.g. by size, color, price, or brand. Multiple filters may
+be applied to take a broad range of products and refine them into a more
+narrow selection, allowing the end user to retrieve the most relevant search
+results based on the criteria they’ve selected.
+
+[Source](https://www.dynamicyield.com/glossary/search-filter/).
+
+#### Configuration Based Development
+
+The difference between configuration-driven development and model-driven
+development is that the former is not restricted to the model of the code
+such as classes, fields, and relationships. Configuration-driven development
+(CCD) encompasses anything that can be configured within your application.
+For example, if your architecture dictates that particular business rules
+must be applied consistently across your application, you can use
+configuration files to configure and apply those rules.
+
+[Source](https://www.ibm.com/developerworks/library/wa-configdev/index.html).
+
+#### Functional Logic Programming
+
+Functional logic programming is the combination, in a single programming
+language, of the paradigms of functional programming (including higher-order
+programming) and logic programming (nondeterministic programming,
+unification). This style of programming is embodied by various programming
+languages, including Curry and Mercury.
+
+[Source](https://en.wikipedia.org/wiki/Functional_logic_programming).
+
+### Map of Repos
+
+The Contexture framework comes to life through a list of repositories
+that individually specialize in some needed layer for our
+architecture. We will be using most (if not all) of these projects in
+our upcoming pages. Let's explore the repos we have so far:
+
+#### Contexture Core
+
+[github.com/smartprocure/contexture](https://github.com/smartprocure/contexture)
+is where our main DSL processor lives. It is a very small layer that
+ties everything together. This one receives the information about the
+different search representations, about the databases involved, and
+the DSL, then outputs the search results respective to each one of the
+queries described in a copy of the received DSL.
+
+You can read more about the core here, [in the repository](https://github.com/smartprocure/contexture).
+
+#### Contexture Providers
+
+The Contexture Providers are the interfacing layer that ties the
+Contexture DSL to the targeted databases. So far, we have only two
+open source providers:
+
+- [contexture-elasticsearch](https://github.com/smartprocure/contexture-elasticsearch)
+- [contexture-mongo](https://github.com/smartprocure/contexture-mongo)
+
+If you are planning to use either ElasticSearch or MongoDB for your
+project, the best way to get started is to use those repositories.
+However, if you need to use Contexture with another database, you will
+need to implement the provider yourself. We're looking for code
+contributors, so please don't feel limited to the current available
+tools. Help us grow together!
+
+#### Contexture Client
+
+The Contexture Client is responsible for triggering behaviors on the
+search interfaces by knowing what causes changes in one or more
+elements of the search tree. It is the key piece of technology that
+allows our search interfaces to work in real time.
+
+You can read more about the Contexture Client here, [in the repository](https://github.com/smartprocure/contexture-client).
+
+#### Contexture React
+
+The Contexture React repository holds a list of components that
+facilitate building search interfaces. They are mainly graphical
+representations of the types that exist on our Contexture Providers.
+
+You can read more about Contexture React here, [in the repository](https://github.com/smartprocure/contexture-client).
+
+## Getting Started
+#### Install Node 9 and NPM
+NodeJS 9 and NPM can be installed through [the list of previous
+releases of NodeJS](https://nodejs.org/en/download/releases/). You
+might get it working with Node 10 (if so, let us know). We haven't
+fully upgraded to Node 10 yet, so until then, we encourage you to at
+least have a working version of Node 9 in hand.
+
+An easy way to move from one version to another is with
+[nvm](https://github.com/creationix/nvm). Here's a command you can run
+to install nvm:
+
+ `curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash`
+
+Please follow [nvm's README](https://github.com/creationix/nvm/blob/master/README.md) for more information.
+
+#### Install Contexture
+Once you have NodeJS and NPM installed, you'll need either a new
+folder for your new project with Contexture, or to go to an existing
+project, then run:
+
+ npm install --save contexture
+
+#### Install Contexture Client
+To install the `contexture-client` you can run the following
+command in your project's root folder:
+
+ npm install --save contexture-client
+
+#### Install Contexture ElasticSearch
+To install the `contexture-elasticsearch` you can also run the
+following command in your project's root folder:
+
+ npm install --save contexture-elasticsearch
+
+#### Install Contexture Mongo
+To install the `contexture-mongo` you can also run the following
+command in your project's root folder:
+
+ npm install --save contexture-mongo
+
+#### Install Contexture React
+To install the `contexture-react` you can also run the following
+command in your project's root folder:
+
+ npm install --save contexture-react
+
+### A First Contexture Script
+With everything installed, let's see a simple script that runs a
+simple one-time search:
+
+```javascript
+let contexture = require('contexture')
+
+let schemas = {
+ collectionNameSchema: {
+ mongo: {
+ collection: 'collectionName'
+ }
+ }
+}
+
+let searchTree = {
+ key: 'root',
+ type: 'group',
+ schema: 'collectionNameSchema',
+ children: [{
+ key: 'namequery',
+ type: 'text',
+ field: 'name',
+ operator: 'containsWord',
+ value: 'text we want to match on the field name',
+ }, {
+ key: 'results',
+ type: 'results'
+ }]
+}
+
+let result = await contexture({
+ schemas,
+ providers: {
+ mongo: require('contexture-mongo')({
+ types: require('contexture-mongo/types')(),
+ getClient: () => ({
+ // Fake mongo client.
+ // For this example we only care about
+ // collection().aggregate([...]).toArray() being a promise.
+ collection: name => ({
+ aggregate: aggregations => ({
+ toArray: async () => ['Unrealistic result example']
+ })
+ })
+ })
+ })
+ },
+}, searchTree)
+
+console.log(result.children[1].context.response.results)
+
+// Explore it yourself!
+result
+```
+
+You can also try this same code in Runkit here:
+
+
+## What it does
+
+Requiring Contexture
+
+```javascript
+let contexture = require('contexture')
+```
+We start by requiring `contexture`. There's nothing much else to see
+here.
+
+
+
+
+Writing the Schemas
+
+```javascript
+let schemas = {
+ collectionNameSchema: {
+ mongo: {
+ collection: 'collectionName'
+ }
+ }
+}
+```
+Immediatly afterwards, we define our schemas. For this specific
+example, we are going to emulate doing a search on a single collection
+of a Mongo database. We define `collectionName` as the name of this
+arbitrary collection. The `schemas` object ends up containing a single
+schema with a key being `collectionNameSchema`, which is going to be
+supported by a single provider `mongo`, from which we'll be looking
+for the `collectionName` collection.
+
+Writing the Contexture DSL
+
+```javascript
+let searchTree = {
+ key: 'root',
+ type: 'group',
+ schema: 'collectionNameSchema',
+ children: [{
+ key: 'namequery',
+ type: 'text',
+ field: 'name',
+ operator: 'containsWord',
+ value: 'text we want to match on the field name',
+ }, {
+ key: 'results',
+ type: 'results'
+ }]
+}
+```
+Our next step is to define a simple search query using Contexture DSL.
+This search query will have a mandatory root group, which among other
+features indicates which schema we will be running this query on
+(`collectionNameSchema`). This node will have two children. The first
+children is going to be our search query. This query will be a `text`
+type query. We're indicating that we want to run a plain text search
+that will try to match any record which `name` contains the word
+`value`. The next node has the `results` type. This is where the
+results will be written once the search runs.
+
+Getting Results
+
+```javascript
+let result = await contexture({
+ schemas,
+ providers: {
+ mongo: require('contexture-mongo')({
+ types: require('contexture-mongo/types')(),
+ getClient: () => ({
+ // Fake mongo client.
+ // For this example we only care about
+ // collection().aggregate([...]).toArray() being a promise.
+ collection: name => ({
+ aggregate: aggregations => ({
+ toArray: async () => ['Unrealistic result example']
+ })
+ })
+ })
+ })
+ },
+}, searchTree)
+```
+
+The next thing we do is to actually run a one-time search. In this
+case, we `await` for `contexture`, passing along some very important
+parameters. First, we pass the schemas we previously defined. Then, we
+pass a providers object, which has the provider for `mongo`. This
+`mongo` key will be matched against the `mongo` key that we defined in
+the schemas, so you could change this property name to something
+entirely different. When we send the mongo provider, we assign the
+result of the initialization of `contexture-mongo`, where we send the
+`contxture-mongo/types` (which **needs to be called as a function once
+required**) and a `getClient` function. In a real schenario, you would
+just send the object that results of `require('mongodb')`. However, to
+provide an exceutable example in the browser, we've made a very small
+Mock of MongoDB where we will return a same object for any collection
+call, which will only allow fake aggregations, which will have a
+promise `toArray` function that will return our `Unrealistic result
+example`.
+
+Keep in mind that since `contexture` returns a promise, you can change
+`await contexture({ /* .. */ })` to `contexture({ /* .. */ }).then()`,
+but you'll need to move the code that we have after the await call
+into the function that is passed on the `.then()` call.
+
+Exploring the Results
+
+```javascript
+console.log(result.children[1].context.response.results)
+
+// Explore it yourself!
+result
+```
+
+Finally, we can use our search result! The output of the search will
+be added to a copy of the original search query. The location of this
+result will be in the children of the `root` node that has the
+`results` type, within a `context` object, within a `response` object,
+on a `results` property. This whole object is going to be exposed in
+the _runkit_ example for you to play with it.
+
+### Connecting to Elasticsearch & MongoDB
+Our primary use case for advanced search interfaces is to query data
+that we store on ElasticSearch and MongoDB. Because of that, we
+provide two contexture libraries for those databases. In this page
+we'll examine how to use these repositories to connect to existing
+Mongo databases and ElasticSearch indexes.
+
+#### Connecting to ElasticSearch
+The followng code example shows how to connect to ElasticSearch:
+
+```javascript
+let Contexture = require('contexture')
+let provider = require('contexture-elasticsearch')
+let types = require('contexture-elasticsearch/types')
+let elasticsearch = require('elasticsearch')
+let AgentKeepAlive = require('agentkeepalive')
+
+let elasticClient = null
+let getClient = () => {
+ if (elasticClient) return elasticClient
+ elasticClient = elasticsearch.Client({
+ minSockets: 1,
+ maxSockets: 20,
+ keepAlive: true,
+ createNodeAgent: (connection, config) =>
+ new AgentKeepAlive(connection.makeAgentConfig(config))
+ })
+ return elasticClient
+}
+
+let schemas = {
+ yourCustomSchemaName: {
+ elasticsearch: {
+ index: 'SomeIndex',
+ type: 'SomeType'
+ }
+ }
+}
+
+let search = Contexture({
+ schemas,
+ providers: {
+ elasticsearch: provider({
+ getClient,
+ request: {
+ headers: {
+ 'custom-header-app-name': 'my-app-sent-this'
+ }
+ },
+ types: types()
+ })
+ }
+})
+```
+
+The code above will provide a working search function `search` that
+will transform any given query into a working ElasticSearch query,
+which will be sent to the database to retrieve the data. Let's examine
+this code in greater detail.
+
+The Dependencies
+
+```javascript
+let Contexture = require('contexture')
+let provider = require('contexture-elasticsearch')
+let types = require('contexture-elasticsearch/types')
+let elasticsearch = require('elasticsearch')
+let AgentKeepAlive = require('agentkeepalive')
+```
+
+The first six lines are about requiring dependencies, the first
+dependency being just `contexture`. The second one is our database
+provider, `contexture-elasticsearch`. Then, we require the types; even
+though you will probably have to write your own types, we have some
+pre-defined types available at `contexture-elasticsearch/types`.
+Lastly, we require `elasticsearch` and `agentkeepalive`, so we can
+actually connect to ElasticSearch and keep it connected even if the
+address becomes unreachable for a while.
+
+Please feel free to dig around these topics by following these links:
+
+- [Contexture Providers](under-the-hood/contexture-providers/README.md).
+- [ElasticSearch.js](https://github.com/elastic/elasticsearch-js).
+- [AgentKeepAlive](https://github.com/node-modules/agentkeepalive).
+
+
+The ElasticSearch Client
+
+```javascript
+let elasticClient = null
+let getClient = () => {
+ if (elasticClient) return elasticClient
+ elasticClient = elasticsearch.Client({
+ minSockets: 1,
+ maxSockets: 20,
+ keepAlive: true,
+ createNodeAgent: (connection, config) =>
+ new AgentKeepAlive(connection.makeAgentConfig(config))
+ })
+ return elasticClient
+}
+```
+
+Now, we define a utility function to connect to ElasticSearch just
+once. The idea here is to be able to re-use the same connection
+instead of using new clients every time a search is executed. We do
+this by declaring a function that will return `elasticClient` if it has
+a truthy value, or otherwise instantiate a new elasticsearch client
+with the given configuration. The configuration we are sending is
+merely an example and shouldn't be used without understanding what is
+being expected by the elasticsearch library. More on the following
+links:
+
+- [ElasticSearch.js docs on configuration](https://github.com/elastic/elasticsearch-js/blob/master/docs/configuration.asciidoc).
+
+
+The Schemas
+
+```javascript
+let schemas = {
+ elasticsearch: {
+ index: 'SomeIndex',
+ type: 'SomeType'
+ }
+}
+```
+
+As shown above, the next thing we do is to define the schemas. This is
+an object which properties are the names of each one of the schemas
+that will be available for the contexture DSL. The schemas for the
+ElasticSearch provider can specify any or all of the following
+properties:
+
+| Option | Type | Description | Required |
+| ------ | ---- | ----------- | -------- |
+| `index` | `string` | Which ES index to use when querying | x |
+| `type` | `string` | Which ES type to use when querying | |
+| `summaryView` | `function` | Used by `results` to return a summary view instead of the whole document, (e.g. for indexes with many fields). Defaults to returning the `hit` property. | |
+| `highlight` | `object` | Used by `results` to determine what fields to highlight, and whether or not they are `inline` (copied over inline on to the source) or `additional` (in a list of additional fields that matched) | |
+| `forceExclude` | `array` | Used by `results` to extend the exclude fields provided on the search tree. The extension happens only if the results node has a `forceExclude` flag set to true.
+
+You can read more about these here:
+
+- [contexture-elasticsearch repository](https://github.com/smartprocure/contexture-elasticsearch).
+
+
+Our Search Function
+
+```javascript
+let search = Contexture({
+ schemas,
+ providers: {
+ elasticsearch: provider({
+ getClient,
+ request: {
+ headers: {
+ 'custom-header-app-name': 'my-app-sent-this'
+ }
+ },
+ types: types()
+ })
+ }
+})
+```
+
+Once we have the schemas set, we can create our `search` function.
+For this purpose, we will be calling `Contexture` with just one
+object. This object will have the `schemas`, and the `providers`. The
+providers will host just one key/value, the one specific for
+`elasticsearch`. The provider, which we required at the beginning of
+the script, needs to be called with the `getClient` function we just
+created and the `types()` that we got from the
+`contexture-elasticsearch/types` repository. We also show that you can
+customize the request headers by providing an object that includes the
+headers keys and values. This `search` function is ready to receive
+search trees and write the results back!
+
+This example and many other important details about
+`contexture-elasticsearch` are accessible in the following links:
+
+- [contexture-elasticsearch repository](https://github.com/smartprocure/contexture-elasticsearch).
+
+#### Connecting to MongoDB
+The followng code example shows how to connect to MongoDB:
+
+```javascript
+let Contexture = require('contexture')
+let provider = require('contexture-mongo')
+let types = require('contexture-mongo/types')
+let MongoClient = require('mongodb').MongoClient
+
+let schemas = {
+ yourCustomSchemaName: {
+ mongo: {
+ collection: 'SomeCollection'
+ }
+ }
+}
+
+let search = null
+
+MongoClient.connect('mongodb://localhost:27017', function(err, client) {
+ search = Contexture({
+ schemas,
+ providers: {
+ mongo: provider({
+ getClient: () => client,
+ types: types()
+ })
+ }
+ })
+})
+```
+
+The code above will provide a working search function `search` that
+will transform any given query into a working MongoDB query,
+which will be sent to the database to retrieve the data. Let's examine
+this code in greater detail.
+
+The Dependencies
+
+```javascript
+let Contexture = require('contexture')
+let provider = require('contexture-mongo')
+let types = require('contexture-mongo/types')
+let MongoClient = require('mongodb').MongoClient
+```
+
+The first lines are about requiring dependencies, the first
+dependency being just `contexture`. The second one is our database
+provider, `contexture-mongo`. Then, we require the types; even
+though you will probably have to write your own types, we have some
+pre-defined types available at `contexture-mongo/types`.
+Lastly, we require `mongodb` to get the much needed `MongoClient`, so
+we can actually connect to the database.
+
+Please feel free to dig around these topics by following these links:
+
+- [Contexture Providers](under-the-hood/contexture-providers/README.md).
+- [MongoDB's NodeJS Package's API](http://mongodb.github.io/node-mongodb-native/3.0/api).
+
+
+The Schemas
+
+```javascript
+let schemas = {
+ yourCustomSchemaName: {
+ mongo: {
+ collection: 'SomeCollection'
+ }
+ }
+}
+```
+
+As shown above, the next thing we do is to define the schemas. This is
+an object which properties are the names of each one of the schemas
+that will be available for the contexture DSL. The schemas for the
+MongoDB provider can specify any or all of the following
+properties:
+
+| Option | Type | Description | Required |
+| ------ | ---- | ----------- | -------- |
+| `collection` | `string` | The MongoDB collection that will be used to run the queries | x |
+
+You can read more about these here:
+
+- [contexture-mongo repository](https://github.com/smartprocure/contexture-mongo).
+
+
+The MongoDB Client & Our Search Function
+
+```javascript
+let search = null
+
+MongoClient.connect('mongodb://localhost:27017', function(err, client) {
+ search = Contexture({
+ schemas,
+ providers: {
+ mongo: provider({
+ getClient: () => client,
+ types: types()
+ })
+ }
+ })
+})
+```
+
+Next we will need to connect to MongoDB. In the previous code, we
+provide an example in which we connect to `mongodb://localhost:27017`,
+and using a callback to the `connect` method, we are able to obtain
+the database client that we need. Once we have this client, we can
+actually create our `search` function. For this purpose, we will
+be calling `Contexture` with just one object. This object will have
+the `schemas`, and the `providers`. The providers will host just one
+key/value, the one specific for `mongo`. The provider, which
+we required at the beginning of the script, needs to be called with
+a `getClient` function that will just return the database client, and
+the `types()` that we got from the `contexture-mongo/types` repository.
+With these steps completed, we end up with a function that is ready to
+receive search trees and write the results back!
+
+You can read more about these topics in the following links:
+
+- [Connecting to MongoDB using the native MongoDB driver for NodeJS](http://mongodb.github.io/node-mongodb-native/api-articles/nodekoarticle1.html#getting-that-connection-to-the-database).
+
+This example and many other important details about
+`contexture-mongo` are accessible in the following links:
+
+- [contexture-mongo repository](https://github.com/smartprocure/contexture-mongo).
+
+### Connecting to Other Databases
+Contexture depends on it's providers to be able to know how to
+translate from the Contexture DSL to the specific DSL that each
+database needs. Because of this, to connect to other databases you
+will need to create a new Provider.
+
+### Simple Search Box
+Building a simple search box consists of a single input field tied to
+any of the fields that any record might have in the specified database
+or index. To be able to make this text input tied to the search
+structure, we will need to bring `contexture-client` in. With that in
+mind, and the knowledge we already have of contexture, we can define
+the following tasks:
+
+1. Create a New Contexture Search Function.
+2. Create a Web Server With a Search Endpoint
+3. Write a Search Tree.
+4. Make the Search Tree Aware of Contexture.
+5. Write a Text Input.
+
+Let's dive in.
+
+Creating a New Conteture Search Function
+
+Just as how we saw in the previous pages, creating a new Contexture
+search function is about setting up the `contexture` package's default
+export with `schemas` and `providers`. In this case, we'll use the
+contexture-mongo approach in the following file (let's call it
+`search.js`):
+
+```javascript
+let Contexture = require('contexture')
+let provider = require('contexture-mongo')
+let types = require('contexture-mongo/types')
+let MongoClient = require('mongodb').MongoClient
+
+let schemas = {
+ collectionNameSchema: {
+ mongo: {
+ collection: 'collectionName'
+ }
+ }
+}
+
+module.exports = {}
+
+MongoClient.connect('mongodb://localhost:27017', function(err, client) {
+ module.exports.search = Contexture({
+ schemas,
+ providers: {
+ mongo: provider({
+ getClient: () => client,
+ types: types()
+ })
+ }
+ })
+})
+```
+
+Note that we're now exporting the search function with
+`module.exports.search = Contexture(...`. You can also note that we
+specified the schema's name to be `collectionNameSchema`, and that any
+search using this schema will be using MongoDb's `collectionName`
+collection.
+
+Create a Web Server With a Search Endpoint
+
+If we want to separate the direct access to the database from the
+client, the previous code should live in the server. Our next step is
+to expose a `/search` endpoint so our future client can reach this
+function. In this section, we'll write a simple web server with
+`express` to satisfy our needs.
+
+Installing the Dependencies
+
+You'll need to install `express` and `body-parser` at the root of your
+project, as follows:
+
+ npm install --save express body-parser
+
+Writing the Web Server
+
+Once you have the dependencies installed, you can set up the server
+with the following code:
+
+```javascript
+let express = require('express')
+let bodyParser = require('body-parser')
+let search = require('./search')
+let app = express()
+
+// create application/json parser
+let jsonParser = bodyParser.json()
+
+app.post('/search', jsonParser, (req, res) => {
+ if (!req.body || !req.body.search) return res.sendStatus(400)
+ search(req.body.search).then((err, result) => {
+ if (err) return res.send(401, err)
+ res.send(200, result)
+ })
+})
+
+app.listen(3000)
+```
+
+You can read more about these topics in the following links:
+
+- [Express Documentation](https://expressjs.com/en/api.html).
+- [body-parser repository](https://github.com/expressjs/body-parser).
+
+
+Writing a Search Tree
+
+Having the DSL processor available through a web server endpoint, we
+can follow up with the structure of the search interface itself. We'll
+conceptualize this by writing the Contexture DSL itself.
+
+Let's use the same `searchTree` that we used in our first
+script:
+
+```javascript
+let searchTree = {
+ key: 'root',
+ type: 'group',
+ schema: 'collectionNameSchema',
+ children: [{
+ key: 'namequery',
+ type: 'text',
+ field: 'name',
+ operator: 'containsWord',
+ value: 'text we want to match on the field name',
+ }, {
+ key: 'results',
+ type: 'results'
+ }]
+}
+```
+
+Keep in mind that we'll be using `collectionNameSchema` since we
+already defined a schema with that name on the server's `search.js`
+file.
+
+Make the Search Tree Aware of Contexture
+
+Having a search tree, we will need `contexture-client` to make it
+smart enough for the user interface. Let's make sure we have it
+available in our project with:
+
+ npm install --save contexture-client
+
+We will also use MobX to make it easier to notify our component that
+the state has changed. For that purpose, we will need to install
+`mobx` using NPM:
+
+ npm install --save mobx
+
+Since we're heavy users of MobX, `contexture-client` already
+provides an adapter that we can use out of the box. Knowing this,
+let's prepare our `contexture-client` to work well with
+`mobx`, as follows:
+
+
+```javascript
+let ContextureClient = require('contexture-client')
+let ContextureMobx = require('contexture-react/dist/utils/contexture-mobx')
+
+let types = ContextureClient.exampleTypes
+let service = async search => ({
+ data: await postData('/sarch', { search })
+})
+
+let Contexture = ContextureMobx({
+ types,
+ service,
+})
+```
+
+Note that our service function will be the one responsible for sending
+the `searchTree` we previously defined to the DSL processor, we can
+wrap the search tree into a smart object that will later react to both
+the user input, and the search results.
+
+```javascript
+let contextureSearchTree = Contexture(searchTree)
+```
+
+You can read more about these topics here:
+
+- [MobX](https://mobx.js.org/).
+- [MobX Observers](https://mobx.js.org/refguide/observer-component.html).
+
+Writing a Text Input
+
+Having the search tree ready allows us to write a `mobx` observer
+component that will receive the tree and react to the result changes
+immediately. Here's an example:
+
+```
+let { observer } = require('mobx')
+let SearchQuery = observer(({ tree }) =>
+ {
+ tree.getNode(['root', 'namequery']).value = e.target.value
+ }}
+ />
+
+let SearchResults = observer(({ tree }) => (
+
+))
+```
+
+Which we would render this way:
+
+```javascript
+
+
+```
+
+This will generate a text input that will trigger a new search every
+time the contents of the input change. This new search will get the
+results and show the results in a JSON form (because of the
+`JSON.stringify` part). Ideally, you will not render them in a JSON
+form, but render them using a list component or table.
+
+### Your First Filter
+In the previous page, we wrote a simple search user interface where a
+single input would retrieve results. Now, we will add a simple filter
+that will allow us to get results within a given range.
+
+#### Adding the Filter to the Tree
+
+The way we will add the filter is by adding a node to the tree. This
+node is going to have a type of `number`, which asks for a `field`, a
+`min` and a `max` values.
+
+```javascript
+let searchTree = {
+ key: 'root',
+ type: 'group',
+ schema: 'collectionNameSchema',
+ children: [{
+ key: 'namequery',
+ type: 'text',
+ field: 'name',
+ operator: 'containsWord',
+ value: 'text we want to match on the field name',
+ }, {
+ key: 'numberrange',
+ type: 'number',
+ field: 'age',
+ min: 0,
+ max: 100
+ }, {
+ key: 'results',
+ type: 'results'
+ }]
+}
+```
+
+With the `numberrange` node added, we can create another component
+with two inputs that will allow us to filter results with the range
+that the user specifies:
+
+```javascript
+let RangeComponent = observer(({ tree }) => (
+
+))
+```
+
+And that's it! Rendering this component will make our search aware of
+any change the user might desire on the minimum and maximum ages they
+might want to use to filter the available results.
+
+### Discovering the Database
+
+One of the great things about Contexture is that it can be used to
+discover the database. In this page, we'll see how to write a filter
+that not only allows the user to refine their search, but that also
+shows information about our data that might not be obvious by looking
+at the results directly.
+
+### The Facet Filter
+
+The `facet` type is just like any other type in the tree. It requires
+a unique key and some other properties. In contrast to previously seen
+types, such as `text` and `number`, facet doesn't require specific
+values, but instead it asks for two properties: `field`, and
+optionally `size`. This type is incredibly useful because besides
+filtering the results based on the `value` (or `values`) the user
+might have chosen, it retrieves from the database a list of available
+values! The `facet` type can be very well represented as a list of
+checkboxes, ready for users to pick for one or more values. Let's see
+how we can use it.
+
+#### Adding the Facet Filter to the Tree
+
+To add the `facet` filter to the tree, we simply add it to the
+structure we already had. For example:
+
+```javascript
+let searchTree = {
+ key: 'root',
+ type: 'group',
+ schema: 'collectionNameSchema',
+ children: [{
+ key: 'namequery',
+ type: 'text',
+ field: 'name',
+ operator: 'containsWord',
+ value: 'text we want to match on the field name',
+ }, {
+ key: 'numberrange',
+ type: 'number',
+ field: 'age',
+ min: 0,
+ max: 100
+ }, {
+ key: 'cityfacet',
+ type: 'facet',
+ field: 'city',
+ value: 'Orlando', // Optional
+ // We could have instead `values` with ['Orlando', 'Miami']
+ }, {
+ key: 'results',
+ type: 'results'
+ }]
+}
+```
+
+Once we have it in the tree, we can simply create another component to
+allow users to set a value to this type. In this case, however, we
+will be retrieving the available values from a field that is
+automatically inserted to this part of the tree. Let's make sure we
+have the data before we render the components.
+
+#### Fetching the Available Options
+
+Having the facet node already added to the tree, it's only matter of
+running a first search before we render the components to actually get
+the possible results from the `facet` type. We can achieve this by
+calling to `contexture-client`'s `refresh` function:
+
+```javascript
+// This would go after:
+// let contextureSearchTree = Contexture(searchTree)
+contextureSearchTree.refresh(['root'])
+```
+
+Now, the available options will be ready to be used at:
+`contextureSearchTree.getNode(['root', 'cityfacet']).context.options`.
+So we can write our facet component this way:
+
+```javascript
+let toggleValue = (array, value) => {
+ if (array.indexOf(value) > -1) {
+ let copy = array.slice() // Making sure it's not a MobX Array
+ copy.splice(array.indexOf(value), 1) // removing value from the array
+ array.replace(copy) // MobX Arrays have this method to replace the array's inner values
+ } else {
+ array.push(value)
+ }
+}
+let RangeComponent = observer(({ tree }) => (
+
+ Select One or More:
+ {tree.getNode(['root', 'cityfacet']).context.options.map(option => (
+
+))
+```
+
+Including this component in our search interface will show the current
+available cities for the search results we have so far, and will allow
+users to filter the search even more by letting them pick any (or many)
+of the available cities.
+
+### IMDB Index
+
+In our Contexture React repository, we've created a Storybook live
+example that uses Contexture (with no server whatsoever, everything in
+the client) to query and discover a public ElasticSearch index with
+data similar to the data that IMDB might contain.
+
+- [Contexture React Repository](https://github.com/smartprocure/contexture-react).
+- More information about [Storybook](https://github.com/storybooks/storybook).
+- [The IMDB Live Index Explorer with Contexture](https://smartprocure.github.io/contexture-react/?selectedKind=Index%20Explorer&selectedStory=Advanced%20Search).
+- [The IMDB Live Index Explorer Source Code](https://smartprocure.github.io/contexture-react/?selectedKind=Index%20Explorer&selectedStory=Advanced%20Search).
+
+Let's see how we can use this tool.
+
+#### Picking a Field
+
+The tool initially shows you a button named `Pick a Field`:
+
+
+
+This button will allow you to select any field on which you might want
+to run a search. If you click it, you'll see the following fields:
+
+
+
+If we pick `Actors`, for example, the search will trigger and results
+will appear:
+
+
+
+Now, let's click on `Select Type` and click on `Facet`. A moment
+afterwards, we will get a list of checkboxes with the most common
+actors among the results:
+
+
+
+We can see that the actor that has made the most movies (among the
+ones idexed) is Naveen Andrews. We can also see the number of movies
+this and other actors have made, and the total actors in the database
+(of which we can only see 10 in this screenshot). Under this list of
+actors, you'll see a text saying `View More`. If you click it, the
+next 10 actors will appear (in order).
+
+At the bottom of the page, you'll see a button labeled `Add Filter`.
+Clicking it will add another interactive component to the website,
+which will say `Click to add AND`.
+
+
+
+Clicking the `Click to add AND` button will show us again a `Pick a
+Field` button:
+
+
+
+So we can start again. Let's say we pick the `Genre` field, and we
+click for the `Facet` type again. A bit later, the list of ordered
+genres will appear:
+
+
+
+And that's it! We're discovering the database with a very simple and
+unpolished interface. By this point you might be curious on what
+components we're using to do all this magic. There's really no trick,
+just follow us through the tutorial. You can also skip some steps if
+you're particularly interested in:
+
+- [Contexture React Repository](https://github.com/smartprocure/contexture-react).
+
+## Querying
+### Contexture DSL
+The Contexture DSL is a JavaScript object structure, or JSON
+structure, that is composed of nested nodes that are equal at all
+levels. Each node has a `key`, a `type` and many other optional
+properties. The first node is called the root and is a node of type
+`group`. Any node of type `group` can have many children. Each
+children can be a node of any type. If any children is another group,
+this children will probably have one or more other children nodes of
+any type, and so on.
+
+Let's begin talking about the root.
+
+#### The Root
+
+The root of a Contexture Tree is a node of type `group`. Group types
+are required to have a `key`, the `type: "group"` property, and an
+array of children `children: [/* nodes */]`. Root groups also need an
+extra property: then ame of the schema. In summary, this is how a root
+node should look:
+
+```javascript
+let searchTree = {
+ key: 'myRootNode',
+ type: 'group',
+ schema: 'mySchemaName',
+ children: [
+ // Other nodes
+ ]
+}
+```
+
+#### The Children
+Each children will be an individual node. Each node will have at least
+a unique `key` (unique per tree, but they can appear again in other
+trees), and a `type`. Some types might require more properties.
+
+That's really all that it is for our DSL. The magic happens in the
+types and the providers. As long as your types are defined properly,
+and your providers build the correct queries and write them back in
+the tree, Contexture will work and you'll be able to use the
+Contexture DSL to build search interfaces of any complexity.
+
+**Note:** Many of the types have some common properties, like `field`
+or `values`. The only reason these properties are common is because
+they've made sense to be common for each one of our specific types,
+not because they have something to share between types. Each type has
+it's own properties and rules, so you should treat them as independent
+structures.
+
+### Interactive Queries
+#### Contexture Client
+Having a Contexture DSL by itself won't work since it's only a
+language and not an interactive or working program in any sense. We
+need something to automatically send this query to our DSL processor
+(the main `contexture` repository). For this purpose, we provide the
+`contexture-client`.
+
+The Contexture Client is responsible for keeping track of the changes
+that happen on the Contexture DSL, either by the user or by the
+Contexture core. The nodes in the Contexture DSL host values used for
+filtering the results, but also hold other properties, such as the
+search results, and a `_meta` object that you can use for debugging
+purposes. In this page, we will sumarize how the Contexture Client
+works with the Contexture DSL to provide real-time interactive
+searches.
+
+##### Initializing the Contexture Client
+The Contexture Client has a default export that needs to be called
+first with some configuration properties before being able to process
+any search. This is how you would normally initialize it:
+
+```javascript
+let ContextureClient = require('contexture-client')
+let Contexture = ContextureClient({
+ service,
+ types,
+})
+```
+
+When Contexture Client determines the search query is ready to be
+executed, it will call the `service` function provided with the whole
+Contexture DSL. It expects to receive another full DSL that it parses
+to then change the nodes again. As previously mentioned, an example
+`service` would be:
+
+```javascript
+let service = async search => ({
+ data: await postData('/sarch', { search })
+})
+```
+
+The `types` property is an object where each key is a type's name.
+These type definitions are different than the ones from the servers
+and allow our Contexture Client to do three things:
+
+- To know how to validate a node.
+- To know what happens to a specific node (and it's suroundings) when
+ it changes.
+- To know how to complemente any missing value on a specific node
+ (default values, so you can omit properties when you write each of
+ the nodes).
+
+Each one of the types will have the following properties:
+
+| Property Name | Type | Description |
+| --- | --- | --- |
+| `validate` | Function | Just as the Provider Type's `hasValue`, this function will let `contexture-client` know wether this node is valid for processing or not. |
+| `reactors` | Object | The Reactors is how each of the node properties might affect this node or other nodes. See our [Introduction to Reactors]() |
+| `defaults` | Object | This object will help in the initialization of the nodes of the tree of this specific type through the definition of some default values on the specified properties. |
+
+##### Context Tree
+Once you have Contexture Client initialized, we will be able to pass
+the Contexture DSL into it. This will generate something we call the
+`Context Tree`, which is an object with the following properties:
+
+| Name | Signature | Description |
+| ---- | --------- | ----------- |
+| add | `async (path, newNode) -> await searchCompleted` | Adds a node to the tree as a child of the specified path. You can await this for when updates settle and relevant searches are completed. |
+| remove | `async path -> await searchCompleted` | Removes a node at the specified path. You can await this for when updates settle and relevant searches are completed. |
+| mutate | `async (path, deltas) -> await searchCompleted` | Mutates the node at the given path with the new values. You can await this for when updates settle and relevant searches are completed. |
+| getNode | `[path] -> node` | Lookup a node by a path (array of keys). |
+| tree | tree | A reference to the internal tree. If you mutate this, you should dispatch an appropriate event. |
+
+You can read more about the instantiated client here: [contexture-client Run Time](https://github.com/smartprocure/contexture-client#run-time).
+
+##### Tree and getNode
+Context Trees have two properties for nagivating through the
+Contexture DSL: `tree` and `getNode`. The `tree` property will have
+the DSL as it was received, plus the default properties set by each
+one of the client types, and some state properties. On the other hand,
+`getNode` is a quick way to access the tree by sending only the keys
+of each node. For example, let's say we have the following DSL:
+
+```javascript
+let searchTree = ContextureClient({
+ key: 'root',
+ type: 'group',
+ schema: 'collectionNameSchema',
+ children: [{
+ key: 'namequery',
+ type: 'text',
+ field: 'name',
+ operator: 'containsWord',
+ value: 'text we want to match on the field name',
+ }]
+})
+```
+
+We are able to access the `namequery` node by simply calling:
+
+```javascript
+let nameQueryNode = searchTree.getNode(['root', 'namequery'])
+```
+
+##### Mutate, Add and Remove
+Once you have a Context Tree ready, you will trigger searches
+automatically by invoking one of the following functions: `add`,
+`remove`, `mutate`. More specifically:
+
+- If you want to run a search after changing some of the properties of
+ a specific node, you would call `mutate`.
+- If you want to add a children to any given `group`, even the root
+ group, you would call `add`.
+- If you want to remove a children to any given `group`, even the root
+ group, you would call `remove`.
+
+Let's see some examples:
+
+Mutate
+
+Mutate allows us to change properties on nodes and trigger search
+afterwards. Here is an example:
+
+```javascript
+await searchTree.mutate(['root', 'namequery'], {
+ value: 'new value'
+})
+```
+
+This will change the tree and produce a new set of results. If you're
+wondering how to keep track of these changes, the simplest way to do
+it is by using our MobX adapter, as shown in our [simple search
+box](../../getting-started/simple-search-box.md) tutorial, or in
+greater detail in our [Managing State](managing-state/README.md) docs.
+
+Add
+
+Having the previous search tree, we can add a children by doing:
+
+```javascript
+await searchTree.add(['root'], {
+ key: 'results',
+ type: 'results'
+})
+```
+
+Remove
+
+We can remove the `results` node we just added by doing:
+
+```javascript
+await searchTree.add(['root', 'results'])
+```
+
+Calling `mutate`, `add` or `remove` will trigger events not only for
+the node that these functions are targetting, but also for nearby
+nodes, depending on the types.
+
+Up next, we'll dig a bit into what are the client side reactors (the
+rules that Contexture Client follows to know what other nodes are
+relevant for each update).
+
+#### Introduction to Reactors
+When any node changes, depending on the type, it might be reasonable
+to re-trigger a search call for other nodes. We call this process the
+selection of `reactors`, where the possible reactors are only three:
+`self`, `others` and `all`.
+
+Reactors should be specified in the Client Types, where each type will
+have a specific reactor for each one of it's properties. For example
+(taken from our client side [example
+types](https://github.com/smartprocure/contexture-client/blob/master/src/exampleTypes.js)):
+
+```javascript
+facet: {
+ reactors: {
+ values: 'others',
+ mode: 'others',
+ size: 'self',
+ optionsFilter: 'self',
+ sort: 'self',
+ }
+}
+```
+
+The client side type defined above will be effective for any node with
+type `facet`, where the properties `values` and `mode` will affect
+only all the other nodes (and not itself), and the properties `size`,
+`optionsFilter` and `sort` will affect only the specific `facet` node
+and no other node.
+
+The one remaining reactor that isn't covered by that example is the
+`all` reactor. The difference between `others` and `all` is that
+`others` excludes the node where the change is happening, and `all`
+includes all other nodes and the node where the change is happening
+(effectively combining `self` and `others`).
+
+
+## Types and Type Components
+### DIY Types
+The Contexture ecosystem provides a defined list of types that can be
+used to perform a wide variety of different searches. Each type we
+offer also has a respective component in our `contexture-react` repo.
+We've made these components so you can quickstart your search interfaces!
+
+Even if our types are focused on the different search interfaces we
+provide, our API is designed to allow you to build any type you might
+need for any other possible use case you might encounter.
+
+We believe that making a generic framework will allow users to be
+creative on their search solutions. Because of that, we will start this
+document by explaining how to build your own types.
+
+#### How to Write a Provider Type
+Initializing Contexture Core
+requires you to send a bunch of types per provider. A type on any
+provider is just a valid string property name on the object that is
+sent, accompanied with a corresponding value of a plain JavaScript
+Object with one or more of the following properties:
+
+| Property | Type | Params (Type) | Return Value Type | What it does |
+| --- | --- | --- | --- | --- |
+| `hasValue` | Function | Node (Object) | Boolean | Allows Contexture to know wether or not to process this search. |
+| `filter` | Function | Node (Object) | Object | Returns a query with the applied input values, which will be sent later to the database provider. |
+| `result` | Function | Node (Object), Search (Function) | Promise | Allows running a direct search for this type before Comtexture sends the full seaech with the whole tree. |
+
+Once you have written a type, you can use it by sending it to an
+existing Contexture Provider. It
+should look more or less like:
+
+```javascript
+let myType = {
+ hasValue: node => node.requiredProperty,
+ filter: node => ({
+ providerQueryObject: {
+ value: node.requiredProperty
+ }
+ })
+}
+
+let provider = MyProvider({
+ types: {
+ myType
+ }
+})
+```
+
+**Type names are not exclusive across providers**. You can define one
+type called `myAwesomeType` in more than one provider and you'll be
+able to keep the same required node properties, thus the same
+`hasValue`. This allows us to provide the same API for several types,
+and re-use code even if we switch the target database of the search.
+
+Once you have a type defined for one or more providers, you should
+write the same type for `contexture-client`.
+
+#### How to Write a Client Type
+Contexture Client already provides a some types based on our
+`Example Types` (more on that later.) These type definitions help
+the client understand how a specific node affects every other node or
+itself.
+
+To create a custom type, you will need to think on the behaviors you
+might need for each one of the following properties:
+
+| Property Name | Type | Description |
+| --- | --- | --- |
+| `validate` | Function | Just as the Provider Type's `hasValue`, this function will let `contexture-client` know wether this node is valid for processing or not. |
+| `reactors` | Object | The Reactors is how each of the node properties might affect this node or other nodes. See our [Introduction to Reactors]() |
+| `defaults` | Object | This object will help in the initialization of the nodes of the tree of this specific type through the definition of some default values on the specified properties. |
+
+More details about `contexture-client` types, their properties and
+their reserved words can be seen on the README of
+[contexture-client](https://github.com/smartprocure/contexture-client#client-types).
+
+The example types are already included in any instantiation
+of Contexture Client's Contexture Tree. However, you can add any type
+you need simply by extending the exposed `exampleTypes` with your own.
+In the following snippet, we initialize a `ContextureTree` with the
+available `exampleTypes`, and our new `myType`:
+
+```javascript
+import * as ContextureClient from 'contexture-client'
+
+let tree = ContextureClient.ContextTree({
+ types: {
+ ...ContextureClient.exampleTypes,
+ myType: {
+ validate: node => node.requiredProperty,
+ reactors: {
+ requiredProperty: 'others',
+ },
+ defaults: {
+ requiredProperty: false
+ }
+ }
+ }
+}, {
+ // Here we will have the underlying tree
+})
+```
+
+#### How to Write a UI Component for a Type
+Writing a user interface for any type can be as simple as writing an
+HTML or JSX Element that will render or modify any property of the
+any node of an existing Contexture Tree, for example, using our custom
+type `myType`, we could write an input field that, onChange, will
+write the field's value into the `requiredProperty`. For example:
+
+```javascript
+// This is ES6+ and JSX
+
+import * as ContextureClient from 'contexture-client'
+
+let tree = ContextureClient.ContextTree(
+ {
+ service: myService,
+ types: {
+ ...ContextureClient.exampleTypes,
+ myType: {
+ validate: node => node.requiredProperty,
+ reactors: {
+ requiredProperty: 'others',
+ },
+ defaults: {
+ requiredProperty: false
+ }
+ }
+ }
+ }, {
+ key: 'root',
+ join: 'and',
+ children: [{
+ key: 'myNode',
+ type: 'myType',
+ }]
+ }
+)
+
+let node = tree.getNode(['root', 'myNode'])
+
+let Component = ({ node }) => (
+ {
+ node.requiredProperty = e.target.value
+ }}
+ />
+)
+```
+
+Now that you have a component you can render it and play with it, but
+the component won't render by itself.
+
+#### The Example Types
+With the intention of providing practical examples of how to write
+types, we decided to share some of the types we use in our production
+applications. These types belong to two different database processors:
+`contexture-elasticsearch` and `contexture-mongo`.
+
+**Example Types aren't the rule**. These types are only provided to
+serve as a guide to build any other type you might need for your
+application. You can also **extend our example types**, simply by
+assigning new types as properties on the objects exposed by
+`contexture-elasticsearch` and `contexture-mongo`.
+
+### ElasticSearch Example Types
+Contexture is designed to target any database you might need. However,
+so far we have only inplemented database providers for the only
+databases that we use: ElasticSearch and Mongo.
+
+Most of our types have relevant components already written to
+facilitate building search interfaces. As we progress over each one of
+these types, we will show small examples of simple components written
+to search with these types. We hope to provide enough information to
+allow you to take as little as you need, or as much as you want, and
+fulfill you expectations.
+
+Our ElasticSearch types are the following ones:
+
+#### Results Type
+
+The `results` node is a node that if present, idicates to Contextre
+that the queries and aggregations should finally run and retrieve all
+the filtered values. It allows some customization properties, as
+shown below:
+
+| Property Name | Type | Description |
+| --- | --- | --- |
+| `page` | Number | Current page of results. |
+| `pageSize` | Number | Total results per page. |
+| `sortField` | String | Field used to sort the results. |
+| `sortDir` | String | Direction of sorting (`asc`, `desc`) |
+
+#### Bool Type
+
+The bool type is intended to work as an ElasticSearch terms
+aggregation with only one value for a single property. This is useful
+for user interfaces with a checkbox to include or exclude a specific
+field from a search (or a specific field-value pair).
+
+Here is the list of all properties this type uses:
+
+| Property Name | Type | Description |
+| --- | --- | --- |
+| field | String | Name of the field that we will be using to filter the search search. |
+| value | String | Value of the field that will be used to filter the search. |
+
+Example input:
+
+```javascript
+{
+ type: 'bool',
+ field: 'fieldName',
+ value: true
+}
+```
+
+Example output:
+
+```javascript
+{
+ term: {
+ fieldName: true
+ }
+}
+```
+
+You can read more about it in:
+
+- [Source code of the type: bool](https://github.com/smartprocure/contexture-elasticsearch/blob/master/src/example-types/bool.js).
+- [Unit tests of the type: bool](https://github.com/smartprocure/contexture-elasticsearch/blob/master/test/example-types/bool.js).
+- Elastic Search [Term Query](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-query.html).
+
+#### Cardinality Type
+
+The Cardinality type serves to calculate an approximate count of the
+distinct available values. This type only uses one property, `field`.
+It returns it's values in the `context` of the node, rather than in
+the `results` node.
+
+Example input:
+```javascript
+{
+ type: 'cardinality',
+ field: 'Organization.Name.untouched'
+}
+```
+
+Example output:
+```javascript
+{
+ aggs: {
+ cardinality: {
+ cardinality: {
+ field: 'Organization.Name.untouched'
+ }
+ }
+ }
+}
+```
+
+You can read more about it in:
+
+- [Source code of the type: cardinality](https://github.com/smartprocure/contexture-elasticsearch/blob/master/src/example-types/cardinality.js).
+- [Unit tests of the type: cardinality](https://github.com/smartprocure/contexture-elasticsearch/blob/master/test/example-types/cardinality.js).
+- Elastic Search [Cardinality Aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-cardinality-aggregation.html).
+
+#### Date Type
+
+The Date type is used to specify a range of dates that will be used to
+filter the available results. This range of dates can be specified by
+a string formatted date (`YYYY-MM-DD`) or by a small set of possible
+humanly readable date ranges. Details follow:
+
+| Property Name | Type | Description |
+| --- | --- | --- |
+| `from` | String | Either a date formatted as `YYYY-MM-DD`, or an ES date (formatted properly for ElasticSearch), or one of the following values: `thisQuarter` (for the current quarter of the year), `lastQuarter` (for the previously completed quarter of the year), `nextQuarter` (for the upcoming quarter). |
+| `to` | String | Optional. Defaults to the current date. Only concidered if there's a `from` value, should be a date formatted as `YYYY-MM-DD` or an ES date (formatted properly for ElasticSearch). |
+| `useDateMath` | Boolean | Defines if we should parse `from` as one of the `*Quarter` dates. |
+| `isDateTime` | Boolean | Ignores any processing or formatting and accpets the `form` and `to` values as they come. |
+
+Example input 1:
+```javascript
+{
+ type: 'date',
+ field: 'fieldName',
+ from: '2016-04-25'
+}
+```
+
+Example output 1:
+```javascript
+{
+ range: {
+ fieldName: {
+ gte: '2016-04-25',
+ format: 'dateOptionalTime'
+ }
+ }
+}
+```
+
+Example input 2:
+```javascript
+{
+ type: 'date',
+ field: 'fieldName',
+ from: 'thisQuarter',
+ useDateMath: true,
+}
+```
+
+Example output 2:
+```javascript
+{
+ range: {
+ fieldName: {
+ gte: moment().quarter(moment().quarter()).startOf('quarter').format('YYYY-MM-DD'),
+ lte: moment.utc(datemath.parse(`${moment().quarter(moment().quarter()).startOf('quarter').format('YYYY-MM-DD')}||+3M-1d/d`)).format('YYYY-MM-DD'),
+ format: 'dateOptionalTime'
+ }
+ }
+}
+```
+
+You can read more about it in:
+
+- [Source code of the type: date](https://github.com/smartprocure/contexture-elasticsearch/blob/master/src/example-types/date.js).
+- [Unit tests of the type: date](https://github.com/smartprocure/contexture-elasticsearch/blob/master/test/example-types/date.js).
+- Elastic Search [Range QUery](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-query.html).
+
+#### Date Histogram Type
+
+The `dateHistogram` type is very useful for retrieving the number of
+results within specific periods of time. The idea here is to end up
+building a chart showing how records have changed over time, for
+example by it's creation date or some other date property. This type
+is able to do this by running a nested stats aggregation inside a
+dateHistogram aggregation, while also supporting for tweaking min/max
+bounds.
+
+This type returns it's values in the `context` of the node, rather
+than in the `results` node.
+
+| Property Name | Type | Description |
+| --- | --- | --- |
+| `key_field` | String | What might be considered a good candidate for the X axis of the chart. |
+| `value_field` | String | What might be considered a good candidate for the Y axis of the chart. |
+| `interval` | | String | Available expressions for interval: `year` (`1y`), `quarter` (`1q`), `month` (`1M`), `week` (`1w`), `day` (`1d`), `hour` (`1h`), `minute` (`1m`), `second` (`1s`). |
+| `boundsRange_min` | Date or String | Lower date limit that will be considered to filter the possible results. |
+| `boundsRange_max` | Date or String | Upper date limit that will be considered to filter the possible results. |
+| `boundsRange_useDateMath` | Boolean | If set to `true`, the min and max ranges will be valid as strings representative of dates, and will be formatted by NPM's library [`@elastic/datemath`](https://github.com/elastic/datemath-js). |
+
+Example input:
+```javascript
+{
+ type: 'dateHistogram',
+ key_field: 'PO.IssuedDate',
+ value_field: 'LineItem.TotalPrice'
+}
+```
+
+Example output:
+```javascript
+{
+ aggs: {
+ max_date: {
+ max: {
+ field: 'PO.IssuedDate',
+ },
+ },
+ min_date: {
+ min: {
+ field: 'PO.IssuedDate',
+ },
+ },
+ twoLevelAgg: {
+ date_histogram: {
+ field: 'PO.IssuedDate',
+ interval: 'year',
+ min_doc_count: 0,
+ },
+ aggs: {
+ twoLevelAgg: {
+ stats: {
+ field: 'LineItem.TotalPrice',
+ },
+ },
+ },
+ },
+ },
+}
+```
+
+You can read more about it in:
+
+- [Source code of the type: dateHistogram](https://github.com/smartprocure/contexture-elasticsearch/blob/master/src/example-types/dateHistogram.js).
+- [Unit tests of the type: dateHistogram](https://github.com/smartprocure/contexture-elasticsearch/blob/master/test/example-types/dateHistogram.js).
+- [Two Level Aggregations in ElasticSearch](https://www.elastic.co/blog/intro-to-aggregations-pt-2-sub-aggregations).
+- [Date Histogram Aggregation in ElasticSearch](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-datehistogram-aggregation.html).
+
+#### Exists Type
+
+The `exists` type is used to check wether some property exsits or not.
+It requires only two fields: `field` and `value`.
+
+| Property Name | Type | Description |
+| --- | --- | --- |
+| `field` | String | The target field we want to check. |
+| `value` | Boolean | the value we want to check. Normally true or false. |
+
+Example input:
+```javascript
+{
+ type: 'exists',
+ field: 'fieldName',
+ value: true
+}
+```
+
+Example output:
+
+```javascript
+{
+ exists: {
+ field: 'fieldName'
+ }
+}
+```
+
+You can read more about it in:
+
+- [Source code of the type: exists](https://github.com/smartprocure/contexture-elasticsearch/blob/master/src/example-types/exists.js).
+- [Unit tests of the type: exists](https://github.com/smartprocure/contexture-elasticsearch/blob/master/test/example-types/exists.js).
+- Elastic Search [Exists Query](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-exists-query.html).
+
+#### Facet Type
+
+The `facet` type represents a list of dynamic choices, e.g. a checkbox
+list filter. We achieve this by running an ElasticSearch terms
+aggregation. We provide a way to limit the number of results that you
+will receive with the `size` property, so that large queries can
+safely be used. For that same purpose, the property `optionsFilter` is
+given, so that search queries can filter the results with a string.
+
+Facet returns it's values in the `context` of the node, rather than in
+the `results` node.
+
+| Property | Type | Default | Description |
+| ---- | ---- | ------- | ----------- |
+| `field` | String | None, *required* | The field it's operating on. |
+| `mode` | String (`include` or `exclude`) | `include` | Wether this filter acts as for the inclusion or exclusion of the selected values when picking up what results to keep. |
+| `values` | Array (of strings) | `[]` | Already selected values. |
+| `fieldMode` | String (`autocomplete`, `word` or `suggest`) | `autocomplete` | Whether to look at the entire field (`autocomplete`), the analyzed words in the field (`word`), or magic suggestions (`suggest`). |
+| `size` | Number | 12 | How many options to return. |
+| `cardinality` | Number | 5000 | Precision threshold override. |
+| `includeZeroes` | Boolean | false | If true, it will include options with 0 matching documents (aka `min_doc_count: 0`) |
+| `optionsFilter` | String | '' | Filters the options further, e.g. a find box above a checkbox list |
+| `caseSensitive` | Boolean | false | Whether options filter is case sensitive. |
+| `sort` | String (`term` or `count`) | `count` | Sort results alphabetically or by count of matching records. |
+
+Example input 1:
+```javascript
+{
+ type: 'facet',
+ field: 'fieldName',
+ values: ['abc', '123']
+}
+```
+
+Example output 1:
+```javascript
+{
+ terms: {
+ 'fieldName.untouched': ['abc', '123']
+ }
+}
+```
+
+Example input with exclude:
+```javascript
+{
+ type: 'facet',
+ field: 'fieldName',
+ mode: 'exclude',
+ values: ['abc', '123'],
+}
+```
+
+Example output with exclude:
+```javascript
+{
+ bool: {
+ must_not: {
+ terms: {
+ 'fieldName.untouched': ['abc', '123'],
+ },
+ },
+ },
+}
+```
+
+You can read more about it in:
+
+- [Source code of the type: facet](https://github.com/smartprocure/contexture-elasticsearch/blob/master/src/example-types/facet.js).
+- [Unit tests of the type: facet](https://github.com/smartprocure/contexture-elasticsearch/blob/master/test/example-types/facet.js).
+- Elastic Search [Terms Query](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-terms-query.html).
+
+#### Geo Type
+
+The `geo` type represents a geographic radius search. It needs a
+geocodeLocation service passed in to it. We currently assume that you
+will be using a google maps geocoder search.
+
+| Property Name | Type | Description |
+| --- | --- | --- |
+| `field` | String (required) | The field it's operating on |
+| `location` | String (required) | Location to geocode (e.g. an address, businessname, anything the google geocode can take) |
+| `radius` | Number (required) | Radius in miles |
+| `operator` | String (either `within` or `not within`) | Whether the filter forces inclusion or exclusion (defaults with `within`). |
+
+Example input:
+```javascript
+{
+ type: 'geo',
+ field: 'fieldName',
+ location: 'SmartProcure',
+ radius: 10,
+ operator: 'within',
+}
+```
+
+Example output:
+
+```javascript
+{
+ geo_distance: {
+ fieldName: '26.3170479,-80.1131784',
+ distance: '10mi',
+ },
+}
+```
+
+You can read more about it in:
+
+- [Source code of the type: geo](https://github.com/smartprocure/contexture-elasticsearch/blob/master/src/example-types/geo.js).
+- [Unit tests of the type: geo](https://github.com/smartprocure/contexture-elasticsearch/blob/master/test/example-types/geo.js).
+- [ElasticSearch's Geo Distance Query](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geo-distance-query.html).
+
+#### Number Type
+
+Number represents a number range with inclusive bounds. This type
+provides the ability to determine the best range values based on
+percentile interval and range threshold.
+
+| Property Name | Type | Description |
+| --- | --- | --- |
+| `field` | String | The field we will be using to filter the results. |
+| `min` | Number | Lower boundary of the filter. |
+| `max` | Number | Upper boundary of the filter. |
+
+Some Notes:
+1. An empty value as the upper boundary represents infinity.
+2. An empty value as the lower boundary represents negative infinity.
+3. Zero has to be respected as a boundary value.
+4. If findBestRange is true it will return the best min and max range.
+
+Example input:
+```javascript
+{
+ type: 'number',
+ field: 'fieldName',
+ min: 500,
+ max: 1000,
+}
+```
+
+Example output:
+
+```javascript
+{
+ range: {
+ fieldName: {
+ gte: 500,
+ lte: 1000,
+ },
+ },
+}
+```
+
+You can read more about it in:
+
+- [Source code of the type: number](https://github.com/smartprocure/contexture-elasticsearch/blob/master/src/example-types/number.js).
+- [Unit tests of the type: number](https://github.com/smartprocure/contexture-elasticsearch/blob/master/test/example-types/number.js).
+
+#### Number Range Histogram Type
+
+The type `numberRangeHistogram` represents a number range with inclusive bounds. This type
+returns feedback in the form of histogram and statistical data.
+This type returns it's values in the `context` of the node, rather
+than in the `results` node.
+
+| Property Name | Type | Description |
+| --- | --- | --- |
+| `field` | String | The field we will be using to filter the results. |
+| `min` | Number | Lower boundary of the filter. |
+| `max` | Number | Upper boundary of the filter. |
+| `percentileInterval` | Number | Used to group the results based on how many of the records are within each one of the sections given by the interval, from the `min` value, up to the `max` value. |
+
+Some Notes:
+1. An empty value as the upper boundary represents infinity.
+2. An empty value as the lower boundary represents negative infinity.
+3. Zero has to be respected as a boundary value.
+
+- [Source code of the type: numberRangeHistogram](https://github.com/smartprocure/contexture-elasticsearch/blob/master/src/example-types/numberRangeHistohgram.js).
+- [Histogram Aggregation in ElasticSearch](https://www.elastic.co/guide/en/elasticsearch/reference/6.1/search-aggregations-bucket-histogram-aggregation.html).
+
+#### Query Type
+
+Query represents a raw elasticsearch query_string. It's mostly used to
+provide a simple sarch box on the user interface.
+
+| Property Name | Type | Description |
+| --- | --- | --- |
+| `field` | String | The field we will be using to filter the results. |
+| `query` | String | String that will be used to match the resulting records, based on the values available for the specified field on each one of the records. |
+| `exact` | Boolean | Wether to match the query text as-is, or to try to be more flexible with the matches (accepting values if they contain the given query, even if the casing doesn't match). |
+
+Example input:
+```js
+{
+ type: 'query',
+ field: 'fieldName',
+ query: 'cable',
+ exact: true,
+}
+```
+
+Example output:
+```js
+{
+ query_string: {
+ query: 'cable',
+ default_operator: 'AND',
+ default_field: 'fieldName.exact',
+ analyzer: 'exact',
+ },
+}
+```
+
+You can read more about it in:
+
+- [Source code of the type: query](https://github.com/smartprocure/contexture-elasticsearch/blob/master/src/example-types/query.js).
+- [Unit tests of the type: query](https://github.com/smartprocure/contexture-elasticsearch/blob/master/test/example-types/query.js).
+
+#### Text Type
+
+Text implements raw text analysis like starts with, ends with, etc.
+These are generally regex queries.
+
+| Property Name | Type | Description |
+| --- | --- | --- |
+| `field` | String | The field we will be using to filter the results. |
+| `join` | String | Either `any`, `all` or `none`. |
+| `operator` | String | `containsWord`, `startsWith`, `wordStartsWith`, `endsWith`, `wordEndsWith`, `is` or `containsExact`. |
+| `values` | Array | Array containing all the words that want to be used as inputs. |
+
+Example input:
+```js
+{
+ type: 'text',
+ field: 'fieldName',
+ join: 'any',
+ operator: 'contains',
+ values: ['laserjet', 'printer'],
+}
+```
+
+Example output:
+```js
+{
+ query_string: {
+ default_field: 'fieldName',
+ default_operator: 'OR',
+ query: '"laserjet" "printer"',
+ },
+}
+```
+
+You can read more about it in:
+
+- [Source code of the type: text](https://github.com/smartprocure/contexture-elasticsearch/blob/master/src/example-types/text.js).
+- [Unit tests of the type: text](https://github.com/smartprocure/contexture-elasticsearch/blob/master/test/example-types/text.js).
+
+#### Other ElasticSearch Example Types
+
+For more informaion about other available example types, please check:
+
+
+### Mongo Example Types
+Most of our types have relevant components already written to
+facilitate building search interfaces. As we progress over each one of
+these types, we will show small examples of simple components written
+to search with these types. We hope to provide enough information to
+allow you to take as little as you need, or as much as you want, and
+fulfill you expectations.
+
+Our MongoDb types are the following ones:
+
+#### Results Type
+
+The `results` node is a node that if present, idicates to Contextre
+that the queries and aggregations should finally run and retrieve all
+the filtered values. It allows some customization properties, as
+shown below:
+
+| Property Name | Type | Description |
+| --- | --- | --- |
+| `page` | Number | Current page of results. |
+| `pageSize` | Number | Total results per page. |
+| `sortField` | String | Field used to sort the results. |
+| `sortDir` | String | Direction of sorting (`asc`, `desc`) |
+
+#### Date Type
+
+The Date type is used to specify a range of dates that will be used to
+filter the available results. This range of dates can be specified by
+a string formatted date (`YYYY-MM-DD`) or by a small set of possible
+humanly readable date ranges. Details follow:
+
+| Property Name | Type | Description |
+| --- | --- | --- |
+| `from` | String | Either a date formatted as `YYYY-MM-DD`, or an ES date (formatted properly for ElasticSearch), or one of the following values: `thisQuarter` (for the current quarter of the year), `lastQuarter` (for the previously completed quarter of the year), `nextQuarter` (for the upcoming quarter). |
+| `to` | String | Optional. Defaults to the current date. Only concidered if there's a `from` value, should be a date formatted as `YYYY-MM-DD` or an ES date (formatted properly for ElasticSearch). |
+| `useDateMath` | Boolean | Defines if we should parse `from` as one of the `*Quarter` dates. |
+| `isDateTime` | Boolean | Ignores any processing or formatting and accpets the `form` and `to` values as they come. |
+
+Example input:
+```javascript
+{
+ type: 'date',
+ field: 'fieldName',
+ from: '2016-04-25'
+}
+```
+
+Example output:
+```javascript
+{
+ fieldName: {
+ $gte: new Date('2016-04-25'),
+ },
+}
+```
+
+You can read more about it in:
+
+- [Source code of the type: date](https://github.com/smartprocure/contexture-mongo/blob/master/src/example-types/date.js).
+- [Unit tests of the type: date](https://github.com/smartprocure/contexture-mongo/blob/master/test/example-types/date.js).
+- MongoDb's [$gte](https://docs.mongodb.com/manual/reference/operator/query/gte/).
+- MongoDb's [$lte](https://docs.mongodb.com/manual/reference/operator/query/lte/).
+
+#### Exists Type
+
+The `exists` type is used to check wether some property exsits or not.
+It requires only two fields: `field` and `value`.
+
+| Property Name | Type | Description |
+| --- | --- | --- |
+| `field` | String | The target field we want to check. |
+| `value` | Boolean | the value we want to check. Normally true or false. |
+
+Example input:
+```javascript
+{
+ type: 'exists',
+ field: 'fieldName',
+ value: true
+}
+```
+
+Example output:
+
+```javascript
+{
+ $and: [
+ {
+ fieldName: {
+ $exists: true,
+ $ne: '',
+ },
+ },
+ {
+ fieldName: {
+ $ne: null,
+ },
+ },
+ ],
+}
+```
+
+You can read more about it in:
+
+- [Source code of the type: exists](https://github.com/smartprocure/contexture-mongo/blob/master/src/example-types/exists.js).
+- [Unit tests of the type: exists](https://github.com/smartprocure/contexture-mongo/blob/master/test/example-types/exists.js).
+- MongoDb's [$exists](https://docs.mongodb.com/manual/reference/operator/query/exists/).
+
+#### Facet Type
+
+The `facet` type represents a list of dynamic choices, e.g. a checkbox
+list filter. We achieve this by running an ElasticSearch terms
+aggregation. We provide a way to limit the number of results that you
+will receive with the `size` property, so that large queries can
+safely be used. For that same purpose, the property `optionsFilter` is
+given, so that search queries can filter the results with a string.
+
+Facet returns it's values in the `context` of the node, rather than in
+the `results` node.
+
+| Property | Type | Default | Description |
+| ---- | ---- | ------- | ----------- |
+| `field` | String | None, *required* | The field it's operating on. |
+| `mode` | String (`include` or `exclude`) | `include` | Wether this filter acts as for the inclusion or exclusion of the selected values when picking up what results to keep. |
+| `values` | Array (of strings) | `[]` | Already selected values. |
+| `size` | Number | 10 | How many options to return. |
+
+Example input:
+```javascript
+{
+ type: 'facet',
+ field: 'fieldName',
+ values: ['abc', '123']
+}
+```
+
+Example input with exclude:
+```javascript
+{
+ type: 'facet',
+ field: 'fieldName',
+ mode: 'exclude',
+ values: ['abc', '123'],
+}
+```
+
+You can read more about it in:
+
+- [Source code of the type: facet](https://github.com/smartprocure/contexture-mongo/blob/master/src/example-types/facet.js).
+
+#### Number Type
+
+Number represents a number range with inclusive bounds. This type
+provides the ability to determine the best range values based on
+percentile interval and range threshold.
+
+| Property Name | Type | Description |
+| --- | --- | --- |
+| `field` | String | The field we will be using to filter the results. |
+| `min` | Number | Lower boundary of the filter. |
+| `max` | Number | Upper boundary of the filter. |
+
+Some Notes:
+1. An empty value as the upper boundary represents infinity.
+2. An empty value as the lower boundary represents negative infinity.
+3. Zero has to be respected as a boundary value.
+4. If findBestRange is true it will return the best min and max range.
+
+Example input:
+```javascript
+{
+ type: 'number',
+ field: 'fieldName',
+ min: 500,
+ max: 1000,
+}
+```
+
+Example output:
+
+```javascript
+{
+ fieldName: {
+ $gte: 500,
+ $lte: 1000
+ }
+}
+```
+
+You can read more about it in:
+
+- [Source code of the type: number](https://github.com/smartprocure/contexture-mongo/blob/master/src/example-types/number.js).
+- [Unit tests of the type: number](https://github.com/smartprocure/contexture-mongo/blob/master/test/example-types/number.js).
+- MongoDb's [$gte](https://docs.mongodb.com/manual/reference/operator/query/gte/).
+- MongoDb's [$lte](https://docs.mongodb.com/manual/reference/operator/query/lte/).
+
+#### Text Type
+
+Text implements raw text analysis like starts with, ends with, etc.
+These are generally regex queries.
+
+| Property Name | Type | Description |
+| --- | --- | --- |
+| `field` | String | The field we will be using to filter the results. |
+| `join` | String | Either `any`, `all` or `none`. |
+| `operator` | String | `containsWord`, `startsWith`, `wordStartsWith`, `endsWith`, `wordEndsWith`, `is` or `containsExact`. |
+| `values` | Array | Array containing all the words that want to be used as inputs. |
+
+Example input:
+```js
+{
+ type: 'text',
+ field: 'fieldName',
+ join: 'any',
+ operator: 'contains',
+ values: ['laserjet', 'printer'],
+}
+```
+
+Example output:
+```js
+{
+ $or: [{
+ fieldName: {
+ $regex: 'laserjet',
+ $options: 'i'
+ }
+ }, {
+ fieldName: {
+ $regex: 'printer',
+ $options: 'i'
+ }
+ }]
+}
+```
+
+You can read more about it in:
+
+- [Source code of the type: text](https://github.com/smartprocure/contexture-mongo/blob/master/src/example-types/text.js).
+- [Unit tests of the type: text](https://github.com/smartprocure/contexture-mongo/blob/master/test/example-types/text.js).
+
+#### Other MongoDb Example Types
+
+For more informaion about other available example types, please check:
+
+
+### Available React Components for Types
+A huge part of working with advanced search interfaces is identifying
+how to portray a specific search filter that you might want to use.
+We've talked about very simple components that react to changes on the
+tree state, but now we'll see how to make it easier for more complex
+nodes to gather the inputs necessary, and also to show the results
+correctly. Here we'll see components specifically crafted for some of
+our providers' example types.
+
+**Notes:**
+- Keep in mind that the theme on these components is purely
+optional.
+- Please be aware that when we refer to `Component`, we mean a
+ Function that returns a valid JSX Element. You can read more here:
+ [Components and
+ Props, on the ReactJS docs](https://reactjs.org/docs/components-and-props.html).
+
+#### Query
+
+
+
+The Query component is probably the most commonly needed for search
+interfaces. It's an input field that allows you to filter results if
+the text matches part of the value of a specfic property on any of the
+records.
+
+Here's how you write a node of type `query` in your _searchTree_:
+```javascript
+{
+ key: 'searchQuery',
+ type: 'query',
+ field: 'title',
+ query: ''
+}
+```
+
+Here is the list of properties that this component expects to have on the node:
+
+| Property Name | Type | Required | Description |
+| --- | --- | --- | --- |
+| `query` | String | No | Search query that should be visible in the component. |
+
+**Note:** The properties present in the search tree that aren't used by the node
+might be needed for the Provider's type.
+
+Here's how you write your component:
+```javascript
+let Query = require('contexture-react/dist/exampleTypes').Query
+// ...
+// Later, on your render function, or where you put your components:
+
+```
+
+This component can be customized by passing any of the following
+properties:
+
+| Property Name | Type | Default Value | Description |
+| --- | --- | --- | --- |
+| `TextInput` | Component | `input` | Text input component. Useful for any style customization, and for libraries that (for example) wrap Bootstrap and it's classes. |
+
+To read more, check the following links:
+
+- [(ElasticSearch Provider) Source code of the query type](https://github.com/smartprocure/contexture-elasticsearch/blob/master/src/example-types/query.js).
+- [(ElasticSearch Provider) Unit tests of the query type](https://github.com/smartprocure/contexture-elasticsearch/blob/master/test/example-types/query.js).
+- [(MongoDb Provider) Source code of the query type](https://github.com/smartprocure/contexture-mongo/blob/master/src/example-types/query.js).
+- [(MongoDb Provider) Unit tests of the query type](https://github.com/smartprocure/contexture-mongo/blob/master/test/example-types/query.js).
+- [Source code of the Query component](https://github.com/smartprocure/contexture-react/blob/master/src/exampleTypes/Query.js).
+
+#### Date
+
+
+
+_(Same goes with the right, not adding another screenshot to avoid
+consuming more space.)_
+
+The Date component helps by allowing users to filter the data to
+obtain results within a specific range of dates. It consists of only
+two date pickers. Here's how you write a node of type `date` in your
+_searchTree_:
+```javascript
+{
+ type: 'date',
+ field: 'fieldName',
+ from: '2016-04-25',
+ to: '2017-05-26'
+}
+```
+
+Here is the list of properties that this component expects to have on the node:
+
+| Property Name | Type | Required | Description |
+| --- | --- | --- | --- |
+| `from` | Date or String (`YYYY-MM-DD` format) | Yes | The initial date of our timeframe. |
+| `to` | Date or String (`YYYY-MM-DD` format) | No | The final date of our timeframe. |
+
+**Note:** The properties present in the search tree that aren't used by the node
+might be needed for the Provider's type.
+
+Here's how you write your component:
+```javascript
+let DateComponent = require('contexture-react/dist/exampleTypes').Date
+// ...
+// Later, on your render function, or where you put your components:
+
+```
+
+This component can be customized by passing any of the following
+properties:
+
+| Property Name | Type | Default Value | Description |
+| --- | --- | --- | --- |
+| `DateInput` | Component | `x => ` | The component that wraps each one of the inputs where the dates end up written by the date-picker. |
+
+To read more, check the following links:
+
+- [(ElasticSearch Provider) Source code of the date type](https://github.com/smartprocure/contexture-elasticsearch/blob/master/src/example-types/date.js).
+- [(ElasticSearch Provider) Unit tests of the date type](https://github.com/smartprocure/contexture-elasticsearch/blob/master/test/example-types/date.js).
+- [(MongoDb Provider) Source code of the date type](https://github.com/smartprocure/contexture-mongo/blob/master/src/example-types/date.js).
+- [(MongoDb Provider) Unit tests of the date type](https://github.com/smartprocure/contexture-mongo/blob/master/test/example-types/date.js).
+- [Source code of the Date component](https://github.com/smartprocure/contexture-react/blob/master/src/exampleTypes/Date.js).
+
+#### DateHistogram
+
+
+
+The DateHistogram component is about representing how many records
+were found during what periods of time. This component currently
+doesn't offer interactive features, but you could use it as
+inspiration to write another one that would allow you to dive in these
+date ranges to see what records appear for each one of them.
+
+Here's how you write a node of type `dateHistogram` in your _searchTree_:
+```javascript
+{
+ key: 'releases',
+ type: 'dateHistogram',
+ key_field: 'released',
+ value_field: 'imdbVotes',
+ interval: '3650d',
+}
+```
+
+**Note:** The properties present in the search tree that aren't used by the node
+might be needed for the Provider's type.
+
+Since this component doesn't need any property from the node itself,
+but only from the results, here's how you write your component:
+```javascript
+let DateHistogram = require('contexture-react/dist/exampleTypes').DateHistogram
+let formatYear = x => new Date(x).getFullYear() + 1
+// ...
+// Later, on your render function, or where you put your components:
+
+```
+
+This component can be customized by passing any of the following
+properties:
+
+| Property Name | Type | Default Value | Description |
+| --- | --- | --- | --- |
+| `background` | Function | `(record, max) => '#ccc'` | A function that returns the background color that is used to render each one of the bars in the resulting chart. |
+| `height` | Number | `100` | Specifies the max height of the whole chart. |
+| `format` | Function | `value => undefined` | Allows you to change the value that each one of the bars has. |
+| `gutter` | Number | `5` | Allows you to specify the spacing between bars. |
+| `yAxis` | Boolean | `false` | Allows you to specify wether you want Y axis information or not. |
+
+To read more, check the following links:
+
+- [(ElasticSearch Provider) Source code of the dateHistogram type](https://github.com/smartprocure/contexture-elasticsearch/blob/master/src/example-types/dateHistogram.js).
+- [(ElasticSearch Provider) Unit tests of the dateHistogram type](https://github.com/smartprocure/contexture-elasticsearch/blob/master/test/example-types/dateHistogram.js).
+- [Source code of the DateHistogram component](https://github.com/smartprocure/contexture-react/blob/master/src/exampleTypes/DateHistogram.js).
+
+#### Facet
+
+
+
+The Facet component allows users to filter the results by picking a
+specific common option among all the values that the records might
+have for a specific field.
+
+Here's how you write a node of type `facet` in your _searchTree_:
+```javascript
+{
+ key: 'facet',
+ type: 'facet',
+ values: ['a'],
+}
+```
+
+Here is the list of properties that this component expects to have on the node:
+
+| Property Name | Type | Required | Description |
+| --- | --- | --- | --- |
+| `values` | Array | Yes | Array of selected values. To have a value selected by default, you will need to know in advance which value to put here, otherwise you can leave this with an empty array and let users select the values themselves. |
+| `size` | Number | No | Max number of options to display. The default is 10. |
+
+**Note:** The properties present in the search tree that aren't used by the node
+might be needed for the Provider's type.
+
+Here's how you write your component:
+```javascript
+let Facet = require('contexture-react/dist/exampleTypes').Facet
+// ...
+// Later, on your render function, or where you put your components:
+
+```
+
+| Property Name | Type | Default Value | Description |
+| --- | --- | --- | --- |
+| `hide.facetFilter` | Object (with an optional single property, `facetFilter`) | `{}` | Allows you to hide the text input that helps on searching for the available options. This text input is very valuable when the results are larger than the available visible results. |
+| `TextInput` | Component | `input` | Allows you to customize the text input. |
+
+To read more, check the following links:
+
+- [(ElasticSearch Provider) Source code of the facet type](https://github.com/smartprocure/contexture-elasticsearch/blob/master/src/example-types/facet.js).
+- [(ElasticSearch Provider) Unit tests of the facet type](https://github.com/smartprocure/contexture-elasticsearch/blob/master/test/example-types/facet.js).
+- [(MongoDb Provider) Source code of the facet type](https://github.com/smartprocure/contexture-mongo/blob/master/src/example-types/facet.js).
+- [(MongoDb Provider) Unit tests of the facet type](https://github.com/smartprocure/contexture-mongo/blob/master/test/example-types/facet.js).
+- [Source code of the Facet component](https://github.com/smartprocure/contexture-react/blob/master/src/exampleTypes/Facet.js).
+
+#### Number
+
+
+
+The Number component allows users to specify a numeric range to filter
+the data based on the available results which values fit within this
+range for a specific field.
+
+Here's how you write a node of type `number` in your _searchTree_:
+```javascript
+{
+ key: 'searchNumber',
+ type: 'number',
+ field: 'metaScore',
+ min: 0,
+ max: 100,
+}
+```
+
+Here is the list of properties that this component expects to have on the node:
+
+| Property Name | Type | Required | Description |
+| --- | --- | --- | --- |
+| `min` | Number | No | Minimum number for the range. |
+| `max` | Number | No | Maximum number for the range. |
+
+**Note:** The properties present in the search tree that aren't used by the node
+might be needed for the Provider's type.
+
+Here's how you write your component:
+```javascript
+let Number = require('contexture-react/dist/exampleTypes').Number
+// ...
+// Later, on your render function, or where you put your components:
+
+```
+
+This component can be customized by passing any of the following
+properties:
+
+| Property Name | Type | Default Value | Description |
+| --- | --- | --- | --- |
+| `NumberInput` | Component | `x => ` | Number input component. Useful for any style customization, and for libraries that (for example) wrap Bootstrap and it's classes. |
+
+To read more, check the following links:
+
+- [(ElasticSearch Provider) Source code of the number type](https://github.com/smartprocure/contexture-elasticsearch/blob/master/src/example-types/number.js).
+- [(ElasticSearch Provider) Unit tests of the number type](https://github.com/smartprocure/contexture-elasticsearch/blob/master/test/example-types/number.js).
+- [(MongoDb Provider) Source code of the number type](https://github.com/smartprocure/contexture-mongo/blob/master/src/example-types/number.js).
+- [(MongoDb Provider) Unit tests of the number type](https://github.com/smartprocure/contexture-mongo/blob/master/test/example-types/number.js).
+- [Source code of the Number component](https://github.com/smartprocure/contexture-react/blob/master/src/exampleTypes/Number.js).
+
+#### ResultCount
+
+
+
+The ResultCount component will only show you the number of visible
+results compared to the number of total results. It's not an
+interactive component.
+
+Most of your Contexture Trees will have a node with type `results`.
+This node posesses information such as the resulting records
+themselves, but also which page you're in, how many
+elements are per page you will receive, and the total records there
+are for this given query, which is what we're looking for for this
+type.
+
+All of these properties are automatically writen by the Contexture
+architecture, so we'll be simply passing the tree and the path to the
+results type node:
+
+```javascript
+let ResultCount = require('contexture-react/dist/exampleTypes').ResultCount
+// ...
+// Later, on your render function, or where you put your components:
+
+```
+
+To read more, check the following links:
+
+- [(ElasticSearch Provider) Source code of the results type](https://github.com/smartprocure/contexture-elasticsearch/blob/master/src/example-types/results.js).
+- [(ElasticSearch Provider) Unit tests of the results type](https://github.com/smartprocure/contexture-elasticsearch/blob/master/test/example-types/results.js).
+- [(MongoDb Provider) Source code of the results type](https://github.com/smartprocure/contexture-mongo/blob/master/src/example-types/results.js).
+- [(MongoDb Provider) Unit tests of the results type](https://github.com/smartprocure/contexture-mongo/blob/master/test/example-types/results.js).
+- [Source code of the ResultCount component](https://github.com/smartprocure/contexture-react/blob/master/src/exampleTypes/ResultCount.js).
+
+#### ResultPager
+
+
+
+The ResultPager component is an interactive component that will show
+you which page you're at (in the middle) and what pages are around
+your current page, as well as some controllers to move forward and
+backwards.
+
+The style of this component isn't very friendly, but it's very easy to
+customize. For more about theme changes, please visit our
+[theming docs](../theming/README.md).
+
+Most of your Contexture Trees will have a node with type `results`.
+This node posesses information such as the resulting records
+themselves, but also which page you're in, how many
+elements are per page you will receive, and the total records there
+are for this given query. We use a combination of those values to get
+how many pages we can move forward (and backwards), and also to move
+around these pages (since our trees react in real time).
+
+All of these properties are automatically writen by the Contexture
+architecture, so we'll be simply passing the tree and the path to the
+results type node:
+
+```javascript
+let ResultPager = require('contexture-react/dist/exampleTypes').ResultPager
+// ...
+// Later, on your render function, or where you put your components:
+
+```
+
+This component can be customized by passing any of the following
+properties:
+
+| Property Name | Type | Default Value | Description |
+| --- | --- | --- | --- |
+| `List` | Component | `div` | The component that wraps the whole list of pages. |
+| `Item` | Component | `span` | The component that wraps each of the available page numbers. |
+| `Link` | Component | `a` | An element that wraps each one of the pagination controls. |
+
+To read more, check the following links:
+
+- [(ElasticSearch Provider) Source code of the results type](https://github.com/smartprocure/contexture-elasticsearch/blob/master/src/example-types/results.js).
+- [(ElasticSearch Provider) Unit tests of the results type](https://github.com/smartprocure/contexture-elasticsearch/blob/master/test/example-types/results.js).
+- [(MongoDb Provider) Source code of the results type](https://github.com/smartprocure/contexture-mongo/blob/master/src/example-types/results.js).
+- [(MongoDb Provider) Unit tests of the results type](https://github.com/smartprocure/contexture-mongo/blob/master/test/example-types/results.js).
+- [Source code of the ResultPager component](https://github.com/smartprocure/contexture-react/blob/master/src/exampleTypes/ResultPager.js).
+
+#### ResultTable
+
+The ResultTable is a component that will display a table with all the
+available results, in which each of the result values will be
+displayed as columns.
+
+the results are automatically writen by the contexture architecture,
+so we'll be simply passing the tree and the path to the results type
+node:
+
+```javascript
+let resulttable = require('contexture-react/dist/exampletypes').resulttable
+// ...
+// later, on your render function, or where you put your components:
+
+```
+
+This component can be customized by passing any of the following
+properties:
+
+| Property Name | Type | Default Value | Description |
+| --- | --- | --- | --- |
+| `Table` | Component | `table` | The component that wraps the table list of results. |
+
+To read more, check the following links:
+
+- [(ElasticSearch Provider) source code of the results type](https://github.com/smartprocure/contexture-elasticsearch/blob/master/src/example-types/results.js).
+- [(elasticSearch Provider) unit tests of the results type](https://github.com/smartprocure/contexture-elasticsearch/blob/master/test/example-types/results.js).
+- [(MongoDb Provider) source code of the results type](https://github.com/smartprocure/contexture-mongo/blob/master/src/example-types/results.js).
+- [(MongoDb Provider) unit tests of the results type](https://github.com/smartprocure/contexture-mongo/blob/master/test/example-types/results.js).
+- [Source code of the ResultTable component](https://github.com/smartprocure/contexture-react/blob/master/src/exampletypes/ResultTable.js).
+
+## Other Components
+### Generally Useful Components
+#### ContextureProvider
+
+This component is a magic tool to make Contexture search interfaces without
+having to write the tree separated. With this component, you can pass the tree
+directly as a plain object, and any children you pass will receive the `tree`
+property directly.
+
+This component receives:
+
+| Property Name | Type | Required | Description |
+| --- | --- | --- | --- |
+| `types` | Object | Yes | Your client-side types, such as the default types of the Contexture Client. |
+| `service` | Object | Yes | The search function that sends the DSL to the initialized Contexture Core. |
+| `nodeKey` | Object | Yes | Key for the root node. Defaults with `root`. |
+| `...props` | Any other property (children excluded) | Yes | Any other property that you might want to send to the initialization of the Contexture Client. |
+
+**Note:** Any of the Contexture React Example Types components automatically
+add the nodes to the tree if the referenced node is not present. _This is
+an experimental feature_.
+
+Here's how you write your component:
+```javascript
+let ContextureProvider = require('contexture-react/dist/ContextureProvider')
+let ContextureClient = require('contexture-client')
+let types = ContextureClient.exampleTypes
+let service = async search => ({
+ data: await postData('/sarch', { search })
+})
+// ...
+// Later, on your render function, or where you put your components:
+
+
+
+```
+
+- [Source code of the ContextureProvider component](https://github.com/smartprocure/contexture-react/blob/master/src/ContextureProvider.js).
+
+#### FilterList
+
+A component that tries to automatically render the specific type components of
+the children of a node.
+
+| Property Name | Type | Required | Description |
+| --- | --- | --- | --- |
+| `node` | Object | Yes | Node of the Contexture Tree where the children that want to be rendered are. |
+| `exampleTypes` | Object | No | Object which a key and a component per type. Defaults in the available example types components in contexture-elasticsearch. |
+| `fields` | Object | Yes | Object which a key and an object with at least a `label` string property, used to indicate the label of each one of the filters. |
+
+Here's how you write your component:
+```javascript
+let FilterList = require('contexture-react/dist/FilterList')
+let ContextureClient = require('contexture-client')
+let tree = ContextureClient({
+ key: 'root',
+ type: 'group',
+ schema: 'mySchema',
+ children: [{
+ key: 'query',
+ type: 'query',
+ field: 'myFieldName',
+ query: 'Something'
+ }]
+})
+// ...
+// Later, on your render function, or where you put your components:
+
+```
+
+- [Source code of the FilterList component](https://github.com/smartprocure/contexture-react/blob/master/src/FilterList.js).
+
+### Layout Components
+#### Awaiter
+
+Renders a loading indicator until a Promise is resolved. It will ender
+an exception (currently just `Ooops...`) if the Promise fails. if the
+Promise passes, the children are rendered.
+
+| Property Name | Type | Required | Description |
+| --- | --- | --- | --- |
+| `promise` | Promise | Yes | Minumum number for the range. |
+
+Here's how you write your component:
+```javascript
+let Awaiter = require('contexture-react/dist/layout/Awaiter')
+let promiseMaker = () => new Promise((resolve, reject)) /* ... */ resolve())
+// ...
+// Later, on your render function, or where you put your components:
+
+
My Crazy Children
+
+```
+
+- [Source code of the Awaiter component](https://github.com/smartprocure/contexture-react/blob/master/src/layout/Awaiter.js).
+
+#### BarChart
+
+Allows you to build your own bar charts (besides just relying on
+the DateHistogram component).
+
+| Property Name | Type | Default Value | Description |
+| --- | --- | --- | --- |
+| `valueField` | String | `''` | The field of each record where the value used for the height of each barnis located. |
+| `categoryField` | String | `''` | The field of each record where the label of each bar is located. |
+| `data` | Array (of Objects with both the `valueField` and the `categoryField`) | `[]` | The data that is going to be used to build the chart. |
+| `height` | Number | `100` | Specifies the max height of the whole chart. |
+| `format` | Function | `value => undefined` | Allows you to change the value that each one of the bars has. |
+| `gutter` | Number | `5` | Allows you to specify the spacing between bars. |
+| `yAxis` | Boolean | `false` | Allows you to specify wether you want Y axis information or not. |
+
+Here's how you write your component:
+```javascript
+let BarChart = require('contexture-react/dist/layout/BarChart')
+// ...
+// Later, on your render function, or where you put your components:
+
+```
+
+- [Source code of the BarChart component](https://github.com/smartprocure/contexture-react/blob/master/src/layout/BarChart.js).
+
+#### SpacedList
+
+Wraps every children in a div with a given style. Useful for (as the
+name portrays) making a spaced list.
+
+| Property Name | Type | Required | Description |
+| --- | --- | --- | --- |
+| `style` | Object | No | The style that will be applied to each div. Defaults in `{ marginBottom: '25px' }`. |
+
+Here's how you write your component:
+```javascript
+let SpacedList = require('contexture-react/dist/layout/SpacedList')
+// ...
+// Later, on your render function, or where you put your components:
+
+
Hi
+
+
+```
+
+- [Source code of the SpacedList component](https://github.com/smartprocure/contexture-react/blob/master/src/layout/SpacedList.js).
+
+#### TextHighlight
+
+Used to highlight content within a text basef on a pattern.
+
+| Property Name | Type | Required | Description |
+| --- | --- | --- | --- |
+| `pattern` | String | No | RegExp pattern used to find matching content. |
+| `text` | String | Yes | Text used as the target of the matches. |
+| `Wrap` | Component | No | Component used to wrap each one of the
+matched. Defaults to `i`. |
+
+Here's how you write your component:
+```javascript
+let TextHighlight = require('contexture-react/dist/layout/TextHighlight')
+// ...
+// Later, on your render function, or where you put your components:
+
+```
+
+- [Source code of the TextHighlight component](https://github.com/smartprocure/contexture-react/blob/master/src/layout/TextHighlight.js).
+
+## Under the Hood
+### Design Principles
+- Intentionally stateless.
+- Detached from state management tools.
+- Can work well with state management tools.
+- Modern ES6+
+- Non-strict functional programming.
+- Configuration based architecture.
+- Focus on a very extensible small core.
+- Small DSL.
+ - Database agnostic.
+ - Isomorphic Tree State.
+ - Optimized for database discovery.
+ - Optimized for advanced search interfaces.
+ - Aiming to be effective for arbitrarily complex database indexes.
+ - Simplicity over performance.
+- Reaction management.
+ - Tree walking.
+ - State flags.
+ - What updates.
+ - Pauses.
+
+### Contexture Core
+The core of Contexture is a package of its own. Located at [github.com/smartprocure/contexture](https://github.com/smartprocure/contexture), it offers the very underlying function that is designed to process every one of the search queries. It begins with a simple curried function which, once the providers and the schemas are received, proceeds to process the [Contexture DSL](#TODO) by walking down the given search tree, cleaning up every node of possible inconsistencies, then mutating the tree with the directions given by the provider types and schemas, up until a valid search query is obtained. This query is delivered to the provider `runSearch` method, and the result is finally added back to the tree.
+
+With this in mind, let's get some specifications.
+
+#### Default Export
+Contexture's default export is a function that receives a total of three parameters, where the first two parameters are curried.
+
+The first argument is expected to be a plain JavaScript Object with two keys:
+
+- `providers`: Should be an object where each key will have a [Contexture Provider](#TODO).
+- `schemas`: Should be an object where each key will have a [Contexture Schema](#TODO).
+
+Calling this function with this object only will return another function, which can be used as an asynchronous search runner. You can also pass in all the arguments as once, but the separation of parameters makes it easier to scope setting up the database providers, the types and the schemas from the search execution.
+
+Example declaration of a search function by passing the schema & providers object first:
+
+```javascript
+const search = Contexture({
+ schemas: {
+ ...mongoSchemas,
+ ...elasticSearchSchemas,
+ },
+ providers: {
+ mongo: require('contexture-mongo')({ /* provider configuration */ }),
+ elasticsearch: require('contexture-elasticsearch')({ /* provider configuration */}),
+ },
+})
+
+// How you might use it with an express-like API:
+// app.use('/search', async req, res) =>
+// res.send(await search(req.body.search))
+```
+
+The other two parameters are the search tree (the Contexture
+DSL), and an optional object that will be sent along to the
+provider's `runSearch` function as the first parameter, that can
+contain any property, but that should at least contain the following
+properties:
+
+| Option | Description |
+| ------ | ----------- |
+| `debug`| Sends `_meta` as part of the response, which includes per node request records, relevant filters, and other debug info. |
+| `onResult` | A callback which is called whenever a node finishes producing it's results, which can be used to send partial results over websockets for example. |
+
+This function, called at least up to the DSL search tree, will return a copy of the given search tree, filled with both properties needed to run the search, but also with the search results, which are assigned in the tree based on each one of the types that each specific search might be using.
+
+#### Process Algorithm
+
+For each of these steps, walk the tree in a parent-first DFS traversal, with each function optionally asynchronous by returning a promise. Along the way, intermediate data is added to contexts on an object called `_meta`. For each context, every type/processor combination is pulled on the fly, meaning it will use the correct local `Provider` and `Type` info even if some contexts have different schemas[^MultiSchema]
+
+- Clean/Prep everything (adding `_meta`, etc)
+- Add `materializedPaths` (used later by `relevantFilters`)
+- Run `filter` for each item if it `hasValue`
+- Add `relevantFilters` for each item (all filters combined in their groups by the `groupCombinator` except for their own filters and any filters related to them in the tree via an `OR`
+- Get `result` for each item if it `hasValidContext` and is not `filterOnly` (as determined by the client event architecture), passing a pre curried search function that includes `relevantFilters` so types don't need to worry about it - logging each request on `_meta.requests`
+- Combine `took` values for all requests to get an accurate number and pass results to `onResult` as they come in if they are defined
+- Unless in `debug` mode, scrub off `_meta` from the response
+
+#### Providers
+All `Provider` must specify the following properties:
+
+- `groupCombinator`
+ - A function that takes the group and an array of its filters and returns them combined.
+- `runSearch`
+ - A function that actually runs the search. It takes the current context, schema, filters (as processed by the `relevantFilters` function and combined with `groupCombinators`), and the criteria for the current context's results (eg `aggs` for an es aggregation or `highlight` for es results). This function can conditionally do different things based on what it is passed - like knowing if it should run an aggregation or a scan/scroll.
+- `types`
+ - A object hash of the `Provider`'s type implementations. It can optionally include a type called `default` whose properties will be used if one of its types are missing something (e.g specifying the default behavior of `validContext` to always allow or prevent results from running)
+
+Additionally, a provider may expose config for it's client (e.g. `hosts` or request `timeout` for elasticsearch).
+
+#### Types
+All `Types` can implement any if the following properties. All are optional:
+
+- `filter`
+ - Takes the current context and produces the filter that will apply to other data contexts in the group (except those related via `OR`). Typically JSON but can be a string as in the SQL case.
+- `hasValue`
+ - Takes the current context and returns a truthy value for whether or not it has a value
+- `result`
+ - Takes the current context, a curried version of the provider's `runSearch` with filters and everything pre-applied (so it is really easy to run searches), the current schema, and the current provider for advanced use cases. This can run one or more async calls - as long as it returns a promise for the final result. If you need to do additional filtering logic, you can use `runSearch` on the provider directly instead of the convenient curried version and inspect the `_meta.relevantFilters` property to see which filters would have been auto-applied, allowing you to do literally any kind of search you want - but there hasn't been a need for this yet.
+- `validContext`
+ - Takes the current context and returns a truthy value for whether or not it should get results.
+
+[^MultiSchema]: This completely solves and obviates the need for the `MultiIndexGroupProcessor` on the client and handles it in much more elegant way (and in a single service call, instead of `n` services calls). A caveat is that it does not currently handle schemas from different providers (because filters are generated based on their context's local schema), so you can't currently mix a elasticsearch schema with a mongo schema (because it could try to call mongo with elastic search filters for example).
+
+#### Schemas
+Schemas are named by convention based on their filename and should be in `camelCase`. A schema must have one or more provider specific set of configuration properties.
+
+### Contexture Client
+#### Process Algorithm
+
+- An action method is called at the top level which:
+ - Interally mutates the tree
+ - Makes one or more calls to `dispatch` with relevant event data
+- For each dispatched event:
+ - Validate the entire tree (an async operation)
+ - Bubble up the tree from the affected node up to the root, and for each node in the path:
+ - Determine affected nodes by calling the reactor for the current event type
+ - Mark each affected node for update, or if it is currently paused, mark that it missed updates
+ - Trigger an update (which is debounced so it does not run right away)
+- When the debounce elapses, an update is triggered:
+ - Check if the update should be blocked
+ - There may be no affected nodes
+ - Some nodes might have erros on validation
+ - Prepare for update - on each node that's markedForUpdate:
+ - Set the lastUpdateTime to now (to enable dropping stale results later in this process)
+ - Set `updating` to true
+ - Serialize the search, omitting all temporary state except lastUpdateTime (which the sever will effectively echo back) and deleting nodes that are filter only with no value
+ - Execute an actual contexture search
+ - For each node in the response:
+ - If the path isn't found in the current tree, ignore it
+ - If the response is empty, ignore it
+ - If the response has a lastUpdateTime earlier than the node in the current tree, ignore it (because it's stale)
+ - If not ignoring the update, mutate the node with the result and set `updating` to false
+- After all of this, the promise for the action/dispatch resolves (so you can await the entire process)
+
+#### Flat Trees
+
+The client maintains a flat tree in addition to the actual tree, which is an object mapped using `flattenTree` from `futil-js`.
+The keys are the array paths encoded as a string, currently using a slashEncoder.
+This allows path lookups to perform in constant time at `O(1)`, drastically speeds up some of the internal tree operations.
+The paths are also stamped on individual nodes for convenience as performing an action on a node requires knowing its path.
+
+#### Initialization
+On instantiation, the client creates a flat tree representation of the tree and stamps the paths on the nodes.
+
+## Examples
+- [contexture-site](https://contexture.site) - Showcase of Contexture searches adapting to diverse datasets such as: car crashes, restaurant locations, COVID-19, SAT scores, school grants, bank failures.
+- [contexture-imdb](https://github.com/smartprocure/contexture-imdb) - An example usage of Contexture to present a search interface for an ElasticSearch index of movie records based on IMDB.
+- [GovSpend](https://app.govspend.com/) - A Contexture web-based tool that makes it easy for government agencies to find a product's best price, identify and validate vendors, request quotes and connect with peers.
+
+
+## Contributing Guide
+See the [SmartProcure Contributor Coding Guidelines](https://github.com/smartprocure/contributor-guide).
+
+## License
+Contexture is licensed under [the MIT License](https://github.com/smartprocure/contexture/blob/master/LICENSE).
diff --git a/docs/CNAME b/docs/CNAME
new file mode 100644
index 0000000..d2b8e1f
--- /dev/null
+++ b/docs/CNAME
@@ -0,0 +1 @@
+docs.contexture.site
\ No newline at end of file
diff --git a/docs/index.html b/docs/index.html
new file mode 100644
index 0000000..d04e7f3
--- /dev/null
+++ b/docs/index.html
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+ Contexture
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+