Skip to content
Simon Y. Blackwell edited this page May 4, 2015 · 20 revisions

Introduction

We start this page with a general overview of JOQULAR patterns, followed by some examples, and then a complete list of JOQULAR predicates and special patterns.

General Format

Patterns take the general format:

<pattern> = {<key>: {<key | operator | predicate | function>:<primitive | deferred | predicate | object>},[...<pattern>]}

Most patterns can be serialized. Those that can't are ones that you pass functions into, e.g. some, every, forall, exists, etc.

Primitive values or objects whose .valueOf() function returns a primitive can be matched without an operator, e.g. {name: 'Joe'}. Without an operator, attempts to match objects whose .valueOf() function does not return a primitive will fail. The JOQULAR classes Time and Duration both resolve to a value of type number.

The pattern matching language is identical for objects and indexed lookups, i.e. the same pattern matching expressions are used for joqularMatch and joqularFind even though one operates against indexes and the other operates against objects.

Whether or not a pattern key value is a literal to be compared or a predicate or provider method to be called on an object being matched is based on the object being matched; hence, a pattern match can operate differently on objects that have literal values or predicate methods or provider methods. For example,

{name: function(value) { return value==='Joe' }.predicate=true}.joqularMatch({name: 'Joe'}); // true
{name: function(value) { return value==='Joe' }.predicate=true}.joqularMatch({name: 'Bill'}); // false
{name: 'Joe'}.joqularMatch({name: 'Joe'}); // true
{name: 'Joe'}.joqularMatch({name: 'Bill'}); // false
{name: function() { return this._name }.provider=true}.joqularMatch({name: 'Joe'}); // potentially true or false

Providers cannot take arguments. Predicates that take multiple arguments do so through the use of an array. Date tests are a great example, e.g. the below example testing for year equality returns true:

{aDate: new Date(2014,0,15,12,30,30,500)}.joqularMatch({aDate: {eq: [new Date(2014,1,26,12,30,30,500),"Y"]) }}); 

Example Patterns

To see these patterns in operation use the file /examples/patterns.html.

// everyone named Joe
{name: 'Joe'} // Note: Only primitives can be matched without an operator.

// everyone named Joe
{name: {eq: 'Joe'}} 

// all adult women
{age: {gte: 18}, gender: 'female'}} 

// adult women Bainbridge Island and downtown Seattle
{age: {gte: 18}, gender: 'female', address: {zipcode: {in: [98110,98101]}}}} 

// all grandsons named the same as their grandfather
{father: {father: {name: {'/': 'name'}}}} 

// all partners who are partnered with the same gender
{partner1: {gender: {'..partner2': 'gender'}}}

// all partners who are not partnered with the same gender
{partner1: {gender: {neq: {'..partner2': 'gender'}}}} 

// Joe's children, if any are sick
{name: 'Joe', {children: {some: function(child) { return child.isSick; }}}} 

// Joe's children, if all are sick
{name: 'Joe', {children: {every: function(child) { return child.isSick; }}}} 

// [], unless all females are named Jo
{gender: 'female', {forall: function(object) { return object.name==='Jo'; }}} 

// all females if any are named Jo
{gender: 'female', {exists: function(object) { return object.name==='Jo'; }}} 

// anyone named Joe or Jo
{name: {soundex: 'Joe'}} 

// anyone with a name starting in Jo
{name: {match: /Jo*/}}

// anyone who is female and authorized based on the value, i.e. 21 or over 
function authorized(value) { return value>=21; }.predicate=true;
{gender: 'female', {age: {$: authorized}}} 

// anyone who is female and authorized based on the object, i.e. a volunteer 
function authorized() { return this.volunteer }.predicate=true;
{gender: 'female', $$: authorized} 

Operators/Predicates

Boolean Number String Object Array Set Date Period Time Duration
lt x x x x x
lte x x x x x
eq x x x x x x x x x x
neq x x x x x x x x x x
gte x x x x x
gte x x x x x
in x x x x x x x x x x
nin x x x x x x x x x x
match x
echoes (soundex) x
position x x
contains x (has) x (has) x x
excludes x x x x
intersects x x x x
disjoint x x x x
coincident x x x x
before x x x x
after x x x x
between x x x x
every x x
some x x
count x x
sum x
avg x
min x
max x
stdev x
variance x

Special Pattern Operators

Pattern Functionality
. x Matches objects when the value from the key in the current object provided as a value for . matches the current value, e.g. {value1: 1, value2:2}.joquularMatch({value1: {'.': 'value2'}}).
.. x Matches objects when the value from the key in the parent object provided as a value for .. matches the current value, e.g. {value: 1, child: {value: 1}}.joqularMatch({child: {'..': 'value'}}).
.. x Matches objects when the value from the key in the parent objects child provided as a value for ..<childkeypath> matches the current value, e.g. {child1: {value: 1}, child2: {value: 1}}.joqularMatch({child1: {value: {'..child2': 'value'}}). can contain sub-paths delimited by ".", e.g. {'../child1.address': 'zipcode'}.
/ x Matches objects when the value from the key in the root object provided as a value for / matches the current value, e.g. {value: 1, child: {value: 1}}.joqularMatch({child: {'/': 'value'}}).
/ x Matches objects when the value from the key in the root objects child provided as a value for /<childkeypath> matches the current value, e.g. {child1: {value: 1}, child2: {value: 1}}.joqularMatch({child1: {value: {'/child2': 'value'}}) can contain sub-paths delimited by ".",e.g. {'/child1.address': 'zipcode'}.
$ x Matches objects when `true' is returned by the function provided as the key value is invoked with the parent key index values as the argument,e.g. joqularFind({age: {$: isNaN}}).
$$ x Matches objects when true is returned by the function provided as the key value is invoked with the objects associated with the parent key index as their 'this` for scope.
@ Reserved Reserved for future implementation of temporal logic.
# Reserved Reserved for future implementation of version logic.
forall x Only applies to patterns submitted to joqularFind. Matches all objects associated with parent key if function associated with forall key returns true for all objects.
exists x Only applies to patterns submitted to joqularFind. Matches all objects associated with parent key if function associated with exists key returns true for any object.