Skip to content
Simon Y. Blackwell edited this page Apr 23, 2015 · 20 revisions

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.

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 regular 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 regular methods. For example,

{name: function(value) { if value==='Joe' }.predicate=true}.joqularMatch({name: 'Joe'}); // true
{name: function(value) { if value==='Joe' }.predicate=true}.joqularMatch({name: 'Bill'}); // false
{name: 'Joe'}.joqularMatch({name: 'Joe'}); // true
{name: 'Joe'}.joqularMatch({name: 'Bill'}); // false
{name: function(value) { return value }}.joqularMatch({name: 'Joe'}); // true
{name: function(value) { return value }}.joqularMatch({name: 'Bill'}); // true

Example Patterns

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

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

// 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 who is under 21 and a authorized, i.e. a volunteer 
function authorized() { return this.volunteer }.predicate=true;
{age: {lt: 21}, {'/': 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
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
touches x x x
every x x
some x 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 object as the argument,e.g. joqularFind({age: {$: 'isNaN'}}) has a pattern that is serializable, whereas joqularFind({age: isNaN}) does not.
@ Reserved Reserved for future implementation of temporal logic.
# Reserved Reserved for future implementation of version logic.
forall x Matches all objects associated with key if function associated with key returns true for all objects.
exists x Matches all objects associated with key if function associated with key returns true for any object.
Clone this wiki locally