Skip to content

Latest commit

 

History

History
352 lines (289 loc) · 18.4 KB

REFERENCE.md

File metadata and controls

352 lines (289 loc) · 18.4 KB

nLinq Reference

nLinq queries are made through a series of calls divided into three main areas:

var result = $from( aSourceArray )      // FROM part
             .equals("aKey1", aValue)   // WHERE part
             .greater("aKey2", 10)      //
             .select()                  // SELECT part

Listed below, there are different combinations of WHERE and SELECT functions that you can use.

FROM

The input should be primarially an array. If a map is provided it will be converted into an array. For streams it can also be a function.

Simple array

var inData  = [ 1, 2, 3 ];
var outData = $from(inData).select();
// [ 1, 2, 3 ]

Array of maps

var inData  = [ { a: 1 }, { a: 2 }, { a: 3 } ];
var outData = $from(inData).select();
// [ {a: 1}, {a: 2}, {a: 3} ]

Simple map

var inData  = { a: 1, b: 2, c: 3};
var outData = $from(inData).select();
// [ 1, 2, 3 ]

Map of maps

var inData  = { a1: { a: 1 }, a2: { a: 2 }, a3: { a: 3 } };
var outData = $from(inData).select();
// [ { a: 1, _key: "a1" }, { a: 2, _key: "a2" }, { a: 3, _key: "a3"} ]

You can specify the key name (instead of "_key") by adding an extra parameter:

var inData  = { a1: { a: 1 }, a2: { a: 2 }, a3: { a: 3 } };
var outData = $from(inData).select();
// [ { a: 1, b: "a1" }, { a: 2, b: "a2" }, { a: 3, b: "a3"} ]

A function

var ll = 0, sum = 0;
var fn = () => ll++;
$from(fn).limit(5).stream(r => sum += r);
// sum = 10 | ll = 6

WHERE

Restriciting prefixes and suffixes

Consider the following example:

var names = [
  { first: "James", last: "Bond" },
  { first: "James", last: "Scott" },
  { first: "Louis", last: "Bond" }
];
Method Description Example
starts Restricts string fields prefix to a value $from(names).starts("first", "J").select() [{"first":"James","last":"Bond"},{"first":"James","last":"Scott"}]
andStarts Restricts string fields prefix to a value in addition to the previous restriction $from(names).starts("first", "J").starts("last", "B").select() [{"first":"James","last":"Bond"}]
notStarts Restricts string fields that are not prefixed by a value $from(names).notStarts("first", "J").select() [{"first":"Louis","last":"Bond"}]
andNotStarts Restricts string fields that are not prefixed by a value in addition to the previous restriction $from(names).starts("first", "J").andNotStarts("last", "S").select() [{"first":"James","last":"Bond"}]
orStarts Restricts string fields prefix to a value in alternative to the previous restriction $from(names).starts("first", "Ja").orStarts("last", "Bo").select() [{"first":"James","last":"Bond"},{"first":"James","last":"Scott"},{"first":"Louis","last":"Bond"}]
orNotStarts Restricts string fields prefix that are not prefixed by a value in alternative to the previous restriction $from(names).starts("first", "Ja").orNotStarts("last", "Sc").select() [{"first":"James","last":"Bond"},{"first":"James","last":"Scott"},{"first":"Louis","last":"Bond"}]
ends Restricts string fields suffix to a value $from(names).ends("last", "nd").select() [{"first":"James","last":"Bond"},{"first":"Louis","last":"Bond"}]
andEnds Restricts string fields suffix to a value in addition to the previous restriction $from(names).ends("first", "es").andEnds("last", "d").select() [{"first":"James","last":"Bond"}]
notEnds Restricts string fields that are not suffixed by a value $from(names).notEnds("last", "Bond").select() [{"first":"James","last":"Scott"}]
andNotEnds Restricts string fields that are not suffixed by a value in addition to a previous restriction $from(names).starts("first", "J").andNotEnds("last", "d").select() [{"first":"James","last":"Scott"}]
orEnds Restricts string fields that are suffixed by a value in alternative to a previous restriction $from(names).starts("first", "J").orEnds("first", "d").select() [{"first":"James","last":"Bond"},{"first":"James","last":"Scott"}]
orNotEnds Restricts string fields that are not suffixed by a value in alternative to a previous restriction $from(names).starts("first", "J").orNotEnds("first", "s").select() [{"first":"James","last":"Bond"},{"first":"James","last":"Scott"}]

Restricting by equality

Method Description Example
andEquals Restricts by a specific value of a field $from(names).equals("firstName", "Scoot").andEquals("lastName", "Tiger").select()
greaterEquals Restricts by a field value greater than or equal to a specific value $from(names).greaterEquals("age", 30).select()
andGreaterEquals Restricts by multiple field values greater than or equal to specific values $from(names).greaterEquals("age", 30).andGreaterEquals("salary", 50000).select()
notGreaterEquals Restricts by a field value not greater than or equal to a specific value $from(names).notGreaterEquals("age", 30).select()
andNotGreaterEquals Restricts by multiple field values not greater than or equal to specific values $from(names).notGreaterEquals("age", 30).andNotGreaterEquals("salary", 50000).select()
orGreaterEquals Restricts by either of the field values being greater than or equal to specific values $from(names).greaterEquals("age", 30).orGreaterEquals("salary", 50000).select()
orNotGreaterEquals Restricts by either of the field values not being greater than or equal to specific values $from(names).notGreaterEquals("age", 30).orNotGreaterEquals("salary", 50000).select()
lessEquals Restricts by a field value less than or equal to a specific value $from(names).lessEquals("age", 30).select()
andLessEquals Restricts by multiple field values less than or equal to specific values $from(names).lessEquals("age", 30).andLessEquals("salary", 50000).select()
andNotLessEquals Restricts by multiple field values not less than or equal to specific values $from(names).notLessEquals("age", 30).andNotLessEquals("salary", 50000).select()
orLessEquals Restricts by either of the field values being less than or equal to specific values $from(names).lessEquals("age", 30).orLessEquals("salary", 50000).select()
orNotLessEquals Restricts by either of the field values not being less than or equal to specific values $from(names).notLessEquals("age", 30).orNotLessEquals("salary", 50000).select()

Restricting by value

Method Description Example
greater Restricts by a field value greater than a specific value $from(names).greater("age", 30).select()
andGreater Restricts by multiple field values greater than specific values $from(names).greater("age", 30).andGreater("salary", 50000).select()
notGreater Restricts by a field value not greater than a specific value $from(names).notGreater("age", 30).select()
andNotGreater Restricts by multiple field values not greater than specific values $from(names).notGreater("age", 30).andNotGreater("salary", 50000).select()
orGreater Restricts by either of the field values being greater than specific values $from(names).greater("age", 30).orGreater("salary", 50000).select()
orNotGreater Restricts by either of the field values not being greater than specific values $from(names).notGreater("age", 30).orNotGreater("salary", 50000).select()
less Restricts by a field value less than a specific value $from(names).less("age", 30).select()
andLess Restricts by multiple field values less than specific values $from(names).less("age", 30).andLess("salary", 50000).select()
notLess Restricts by a field value not less than a specific value $from(names).notLess("age", 30).select()
andNotLess Restricts by multiple field values not less than specific values $from(names).notLess("age", 30).andNotLess("salary", 50000).select()
orLess Restricts by either of the field values being less than specific values $from(names).less("age", 30).orLess("salary", 50000).select()
orNotLess Restricts by either of the field values not being less than specific values $from(names).notLess("age", 30).orNotLess("salary", 50000).select()
between Restricts by a field value between two specific values $from(names).between("age", 20, 30).select()
andBetween Restricts by multiple field values between specific values $from(names).between("age", 20, 30).andBetween("salary", 40000, 60000).select()
andNotBetween Restricts by multiple field values not between specific values $from(names).notBetween("age", 20, 30).andNotBetween("salary", 40000, 60000).select()
orBetween Restricts by either of the field values being between specific values $from(names).between("age", 20, 30).orBetween("salary", 40000, 60000).select()
orNotBetween Restricts by either of the field values not being between specific values $from(names).notBetween("age", 20, 30).orNotBetween("salary", 40000, 60000).select()
betweenEquals Restricts by a field value between or equal to two specific values $from(names).betweenEquals("age", 20, 30).select()
andBetweenEquals Restricts by multiple field values between or equal to specific values $from(names).betweenEquals("age", 20, 30).andBetweenEquals("salary", 40000, 60000).select()
andNotBetweenEquals Restricts by multiple field values not between or equal to specific values $from(names).notBetweenEquals("age", 20, 30).andNotBetweenEquals("salary", 40000, 60000).select()
orBetweenEquals Restricts by either of the field values being between or equal to specific values $from(names).betweenEquals("age", 20, 30).orBetweenEquals("salary", 40000, 60000).select()
orNotBetweenEquals Restricts by either of the field values not being between or equal to specific values $from(names).notBetweenEquals("age", 20, 30).orNotBetweenEquals("salary", 40000, 60000).select()

Restricting by value matching

Method Description Example
contains
andContains
andNotContains
orContains
orNotContains
empty
andEmpty
andNotEmpty
orEmpty
orNotEmpty
match
andMatch
andNotMatch
orMatch
orNotMatch

Restricting by value type

Method Description Example
type
andType
andNotType
orType
orNotType
Method Description Example
is
andIs
andNotIs
orIs
orNotIs
or
and
not
andNot
orNot

Changing the current result set

Method Description Example
each
intersect
except
union
cartesian
attach
sort
assign
join
skip
take
skipTake
define
removed
stream
streamFn

SELECT

Method Description Example
select Returns all fields from the original array $from(anArray).select()
select (selected fields) Returns specific fields with corresponding default values $from(anArray).select({ f1: "n/a", f2: false })
select (transform function) Returns the result of the transformation function $from(anArray).select(r => ({ f1: r.f1, f2: r.a1 + r.a2 }))
min Returns the minimum value of a field from the result $from(anArrayOfTemperatures).min("temperature")
max Returns the maximum value of a field from the result $from(anArrayOfTemperatures).max("temperature")
average Returns the average value of a field from the result $from(anArrayOfTemperatures).average("temperature")
sum Returns the sum value of a field from the result $from(anArrayOfFiles).sum("size")
distinct Returns an array of distinct values for a specific field from the result $from(anArrayOfMeasures).distinct("measureName")
group Returns a map grouping the array of records by a specific field from the result $from(anArrayOfTemperatures).group("city")
at Returns a single entry of the result set $from(anArray).at(23)
all Returns true if all records from the original array are present on the final result set (false otherwise) $from(anArray).all()
count Returns the number of records of the final result set $from(anArray).count()
countBy Returns an array counting records per each value after grouping the array of records by a specific field from the result $from(anArray).countBy("groupByFieldName1,groupByFieldName2", "countRecordsFieldName", "keyFieldNameToUseOnResult1,keyFieldNameToUseOnResult2")
first Returns the first record of the final result set $from(anArray).first()
last Returns the last record of the final result set $from(anArray).last()
any Returns true if the result set has any record at all (false otherwise) $from(anArray).any()
none Returns true if the result set is empty (false otherwise) $from(anArray).none()
reverse Returns a reverse order result set $from(anArray).reverse()
limit Returns just a limited amount of records of the result set $from(anArray).limit(5)
head Returns a limited amount of the first records of the result set $from(anArray).head(10)
tail Returns a limited amount fo the last records of the result set $from(anArray).tail(10)

Simple select

Return the current result set with the WHERE part applied:

var result = $from([ 1, 2, 3 ]).select();
// [ 1, 2, 3 ]

Select the fields

Return the current result set with the WHERE part restricting each map entry on the result to the fields provided and their default values in case they are not present:

var inData = [ 
    { name: "Point 1", x: 1, y: -1 }, 
    { name: "Point 2", x: 5, y: -5 },
    { x: 3 }
]; 
var result = $from(inData).select({ x: 0, y: 0 });
// [ { x: 1, y: -1 },
//   { x: 5, y: -5 },
//   { x: 3, y: 0  } ]

Transform function

The result set will be transformed by the provided function:

var inData = [
    { name: "Vector 1", x1: 2, y1: -1, x2: 5, y2: -10 },
    { name: "Vector 2", x1: -2, y1: -1, x2: 5, y2: 10 }
];
var result = $from(inData).select(r => {
    var newResult = { name: r.name };

    newResult.distance = Math.round( Math.sqrt( Math.pow(r.x1-r.x2, 2) + Math.pow(r.y1-r.y2, 2)));

    return newResult;
});
// [ { name: "Vector 1", distance: 9 },
//   { name: "Vector 2", distance: 13} ]

Select into a map of maps

The result set can be transformed into a map of maps by provided an index field:

var inData  = [ { a: 1, b: "a1" }, { a: 2, b: "a2" }, { a: 3, b: "a3" } ];
var outData = $from(inData).select(void 0, "b");
// { "a1": {"a":1,"b":"a1"}, "a2": {"a":2,"b":"a2"}, "a3":{"a":3,"b":"a3"} }

QUERY

It's also possible to provide all the query as a map instead of method calls. To do this you can use:

var result = $from(anArrayOfData).query(aQueryMap)

The query map to provide to the query method is composed of 3 or 4 parts depending on the use:

aQueryMap = { where: [], transform: [], select: {} }

// or

aQueryMap = { where: [], transform: [], selector: {} }

The following example is provided in YAML with comments to make it easier to visualize:

# 1. The where part is composed of an array of conditions and arguments that limit the data
where:
## This is the same as doing .equals("isFile", true)
- cond: equals
  args:
  - isFile
  - true
# 2. The transform part is composed of an array of functions and arguments that transform the data
transform:
## These are the same as doing .attach("lastAccess", elem => new Date(elem.lastAccess)).sort("-size")
- func: attach
  args:
  - lastAccess
  - !!js/eval elem => new Date(elem.lastAccess)
- func: sort
  args:
  - "-size"
# 3. The select part if composed of the same map you would provide to a .select method
## This is equivalent to .select({ filename: "n/a", size: -1 })
select:
  filename: n/a
  size    : -1
# 4. The selector part as an alternative to part 3 allows the use of selector functions
## selector:
### This is equivalent to .at(0)
##  func: at
##  args:
##  - 0

NOTE: As you can see each part (with the exception of select) is always an array of maps or a single map with a function name (cond/func) followed by an array of the corresponding arguments (args). There are no restrictions on the functions you should use on where or transform. The only difference between where/transform and select/selector is that select/selector are functions that cannot be chained and will return a result.

In the end this yaml could be provided as a JSON map to the query method like this:

aQueryMap = { where: [ { cond: "equals", args: [ "isFile", true ] } ], transform: [ { func: "attach", args: [ "lastAccess", elem => new Date(elem.lastAccess) }, { func: "sort", args: "-size" ], select: { filename: "n/a", size: -1 } }

Translation: Will filter an array of map for the entries where the field isFile is true, will add/replace the field attach converting it into a javascript Date, then sort the resulting array by biggest values on the field size (descending order) and returning an array of maps as a result with two fields: filename and size. If filename is not defined for some entry it will be represented as "n/a"; if size is not defined for some entry it will be represented as -1.

Similary using a selector the JSON map to the query method would look like:

aQueryMap = { where: [ { cond: "equals", args: [ "isFile", true ] } ], transform: [ { func: "attach", args: [ "lastAccess", elem => new Date(elem.lastAccess) }, { func: "sort", args: "-size" ], selector: { func: "at", args: [ 0 ] } }

Translation: Will filter an array of map for the entries where the field isFile is true, will add/replace the field attach converting it into a javascript Date, then sort the resulting array by biggest values on the field size (descending order) and returning only the map, on position 0, of the resulting array of maps.