# Search criteria component

(by pavel, last update: sep 2013)

Main goal is to provide "rich" search functionality.

## Mockups

![A row](https://camo.githubusercontent.com/a46d1911f7113aa1162a0d11a80cf7fa61705fe9/68747470733a2f2f7472656c6c6f2d6174746163686d656e74732e73332e616d617a6f6e6177732e636f6d2f3531333463303362366238616362623933393030346631372f3532343238303833653539643761636636373030303338302f61613531386637313933313838653734616130653938393531666635666530632f7365617263685f726f772e706e67)

![A list of saved searches](https://camo.githubusercontent.com/6f4ab02458a67b90a94d8b9821b56e66d808247d/68747470733a2f2f7472656c6c6f2d6174746163686d656e74732e73332e616d617a6f6e6177732e636f6d2f3531333463303362366238616362623933393030346631372f3532343238303833653539643761636636373030303338302f65653165313231396236366230393836316266366163653432663832613262382f7365617263685f73617665645f66696c7465725f64726f70646f776e2e706e67)

![Two rows](https://camo.githubusercontent.com/1fcf1cfa766cf62cdcf2b4d99fd3b8ee44b006ca/68747470733a2f2f7472656c6c6f2d6174746163686d656e74732e73332e616d617a6f6e6177732e636f6d2f3531333463303362366238616362623933393030346631372f3532343238303833653539643761636636373030303338302f36626564633933353165376538353265373833623861383661656265316136352f7365617263685f74776f5f726f77732e706e67)

![Save dialog](https://camo.githubusercontent.com/40ff450021e581822780e04984ed5e48df841dee/68747470733a2f2f7472656c6c6f2d6174746163686d656e74732e73332e616d617a6f6e6177732e636f6d2f3531333463303362366238616362623933393030346631372f3532343238303833653539643761636636373030303338302f66656234613834653365383630386131613032383337386238376533303033642f7365617263685f736176655f6469616c6f672e706e67)

## Criteria JSON example

```
var criteria =
  {
    'type': 'and',
    'children': [
      {
        'type': 'not',
        'children': [
          {
            'type': 'tags',
            'operator': 'include',
            'operands': ['toy', 'walthers']
          }
        ]
      },
      {
        'type': 'response_code',
        'operator': 'is_equal_to',
        'operands': [200]
      }
    ]
  }
```

## Implementation pieces

* A criteria graph (in particular a list of individual criteria) to express selected search criteria
* UI component to represent criteria
  * show an empty criteria list
  * add a new criteria row
  * save a named list
  * show already stored (in previous sessions) lists
  * "polymorphic" criteria row: an ability to show different criteria types and change inputs base on previous selections dynamically. For example if a user selects "response code" criteria, a row will change the next drop-down to show response code specific options.
* "Criteria to ES" mapper to translate criteria list. If JSON representation of criteria will mimic ElasticSearch, the item will be get for free. The other mappers (at least "criteria to mongo") should also be considered.

## Implementation approaches

**Plain old ruby objects**

* Criteria list is implemented using plain "conventional" ruby.
* Requires additional coding to implement serialization/deserialization
* Requires additional coding to store saved criteria in a database
* Requires additional coding for validation
* More flexible and allow for example move from a list to a tree of criteria if it is needed
* Polymorphic criteria is implemented using ruby inheritance and composition

**ActivieRecord**

* Saved search as one-to-many association (search to criterion items)
* Locked on the list representation of the saved search. Moving to "trees" is harder
* "Save" functionality for free.
* "Validation" for free
* Polymorphic criteria is implemented using ActiveRecord STI
* "Include/Exlude" functionality is implemented as a boolean flag on Criteria class

**Purely JavaScript implementation**

Intentionally left blank :)

## TBD

_How the criteria component coordinates with the "search" input? In particular, if both components (criteria rows and input) are filled, should we use AND or OR?_

_Should JSON representation of criteria be exactly like ES JSON looks like?_

_If ActiveRecord implementation is chosen, will we use a single "data" serialized column for different criteria kinds, or dedicated columns for specific attributes of criteria (sparse table)?_
