simple queries are supported (entire segments), however a DSL is provided
for easier querying. The client can perform and
, or
, and not
operations
on results if they are retreived as buffers (see example below in DSL area).
- Simple query, all results returned:
await segmenta.add("my-new-segment", [ 10, 20, 30 ]);
const result = await segmenta.query("my-new-segment");
- Paged query:
await segmenta.add("paged-results-segment", [ 1, 2, 3, 4, 5 ]);
const result1 = await segmenta.query({
query: "paged-results-segment",
skip: 0,
take: 2
});
const result2 = await segmenta.query({
query: "63c6a1f0-8aec-4249-9d80-63c5de13b942",
skip: 2
});
- Paged results are snapshot and can be re-queried by using their id (uuid). Snapshots automatically expire
after 24 hours (or the number of seconds specified by
resultsTTL
in your constructor arguments. You may
manually dispose of results when you no longer need them:
const result = await segmenta.query({ query: "my-set", skip: 0, take: 10 });
await segmenta.dispose(result.resultSetId);
Snapshots are only created when queries are performed with a positive integer skip
or take
value
There is a DSL for querying in a more readable manner:
await segmenta.add("set1", [ 1, 2 ]);
await segmenta.add("set2", [ 3, 4, 5 ]);
await segmenta.add("set3", [ 2, 3, 5, 6, 7 ]);
await segmenta.add("set4", [ 5, 6 ]);
// ... some time later ...
const query = "get where in 'set1' or 'set2' and 'set3' not 'set4'";
const result1 = await segmenta.query(query);
// or, with paging options:
const result2 = await segmenta.query({ query, skip: 10, take: 100 });
// the query syntax above is analogous to the following
// more manual query mechanism:
const set1 = await segmenta.getBuffer("set1");
const set2 = await segmenta.getBuffer("set2");
const set3 = await segmenta.getBuffer("set3");
const set4 = await segmenta.getBuffer("set4");
// these operations are fast, acting on bitfields in memory.
const final = set1 // [ 1, 2 ]
.or(set2) // [ 1, 2, 3, 4, 5 ]
.and(set3) // [ 2, 3, 5 ]
.not(set4) // [ 2, 3 ]
.getOnBitPositions()
.values; // returns the numeric array for bit positions
One may also query for counts only:
await segmenta.query("count where in 'x');
One may also query for results to come back in a random order:
await segmenta.query("random where in 'x');
When paging is requested and a resultSetId
is returned, requering against
that result-set will maintain the original randomized order.
Query syntax is quite simple:
(GET | COUNT | RANDOM) WHERE IN('segment-id')
[(AND|OR|NOT) IN('other-segment')]...
[MIN {int}]
[MAX {int}]
[SKIP {int}]
[TAKE {int}]
- segments are identified by strings (single- or double-quoted)
- only two operations are supported:
GET
and COUNT
- the results of
COUNT
look like GET
except no segment data is returned. Use
the total
field in the result to read your count value. - boolean operations are run left-to-right
- operations may be grouped with brackets, in which case they are evaluated first, eg:
GET WHERE IN('x') AND NOT (IN('y') OR IN('z'))
- retreives values which are in 'x' and also not in 'y' or 'z';
- brackets around segment ids are optional:
GET WHERE IN 'x'
is equivalent to GET WHERE IN('x')
- the
IN
keyword is optional after the first usage:
GET WHERE IN 'x' and IN 'y'
is equivalent to GET WHERE IN 'x' AND 'y'
- syntax is case-insensitive
GET WHERE IN 'x'
is equivalent to get where in 'x'
and Get Where In('x')
skip
and take
can also be set on the query options -- when doing so, the skip/take
values on query options take precedence. This allows easy re-use of natural-language
query with changing paging values, but also facilitates natural language paging if that
is your preference.MIN
and MAX
set minimum and maximum values to bring back in the result set. These
values are inclusive. This may be useful if SKIP
doesn't suit your chunking needs,
but rather setting a MIN
and a TAKE
min
and max
can also be set on query options. As with skip
and take
, the query
options values for min
and max
override any natural language specification- segment ids are case-sensitive
get where in 'MY-SEGMENT'
is NOT equivalent to get where in 'my-segment'
- segment ids may not contain quotations
- they must be valid redis keys
- some queries will never make sense, so expect either strange results or parse errors:
GET WHERE NOT IN 'x'
- since the segments are open-ended, this is essentially an infinite set of
all numbers, excluding those in segment 'x'