npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

rql

v0.3.3

Published

Query language for the web, NoSQL

Downloads

8,484

Readme

Build Status

Resource Query Language (RQL) is a query language designed for use in URIs with object style data structures. This project includes the RQL specification and provides a JavaScript implementation of query parsing and query execution implementation for JavaScript arrays. The JavaScript library supports AMD and NodeJS/CommonJS module format so it can be run in the browser or in the server. RQL can be thought as basically a set of nestable named operators which each have a set of arguments. RQL is designed to have an extremely simple, but extensible grammar that can be written in a URL friendly query string. A simple RQL query with a single operator that indicates a search for any resources with a property of "foo" that has value of 3 could be written:

eq(foo,3)

RQL is a compatible superset of standard HTML form URL encoding. The following query is identical to the query (it is sugar for the query above):

foo=3

Such that this can be used in URIs like:

http://example.org/data?foo=3

JavaScript Library

Using the JavaScript library we can construct queries using chained operator calls in JavaScript. We could execute the query above like this:

var Query = require("rql/query").Query;
var fooEq3Query = new Query().eq("foo",3);

RQL Rules

The RQL grammar is based around standard URI delimiters. The standard rules for encoding strings with URL encoding (%xx) are observed. RQL also supersets FIQL. Therefore we can write a query that finds resources with a "price" property below 10 with a "lt" operator using FIQL syntax:

price=lt=10

Which is identical (and sugar for call operator syntax known as the normalized form):

lt(price,10)

One can combine conditions with multiple operators with "&":

foo=3&price=lt=10

Is the same as:

eq(foo,3)&lt(price,10)

Which is also the same as:

and(eq(foo,3),lt(price,10))

We can execute a query against a JavaScript array:

require("rql/js-array").executeQuery("foo=3&price=lt=10", {}, data)...

The | operator can be used to indicate an "or" operation. We can also use paranthesis to group expressions. For example:

(foo=3|foo=bar)&price=lt=10

Which is the same as:

and(or(eq(foo,3),eq(foo,bar)),lt(price,10))

Values in queries can be strings (using URL encoding), numbers, booleans, null, undefined, and dates (in ISO UTC format without colon encoding). We can also denote arrays with paranthesis enclosed, comma separated values. For example to find the objects where foo can be the number 3, the string bar, the boolean true, or the date for the first day of the century we could write an array with the "in" operator:

foo=in=(3,bar,true,2000-01-01T00:00:00Z)

We can also explicitly specify primitive types in queries. To explicitly specify a string "3", we can do:

foo=string:3

Any property can be nested by using an array of properties. To search by the bar property of the object in the foo property we can do:

(foo,bar)=3

We can also use slashes as shorthand for arrays, so we could equivalently write the nested query:

foo/bar=3

Another common operator is sort. We can use the sort operator to sort by a specified property. To sort by foo in ascending order:

price=lt=10&sort(+foo)

We can also do multiple property sorts. To sort by price in ascending order and rating in descending order:

sort(+price,-rating)

The aggregate function can be used for aggregation. To calculate the sum of sales for each department:

aggregate(departmentId,sum(sales))

Here is a definition of the common operators (individual stores may have support for more less operators):

  • sort(<+|-><property) - Sorts by the given property in order specified by the prefix (+ for ascending, - for descending)
  • select(<property>,<property>,...) - Trims each object down to the set of properties defined in the arguments
  • values(<property>) - Returns an array of the given property value for each object
  • aggregate(<property|function>,...) - Aggregates the array, grouping by objects that are distinct for the provided properties, and then reduces the remaining other property values using the provided functions
  • distinct() - Returns a result set with duplicates removed
  • in(<property>,<array-of-values>) - Filters for objects where the specified property's value is in the provided array
  • out(<property>,<array-of-values>) - Filters for objects where the specified property's value is not in the provided array
  • contains(<property>,<value | expression>) - Filters for objects where the specified property's value is an array and the array contains any value that equals the provided value or satisfies the provided expression.
  • excludes(<property>,<value | expression>) - Filters for objects where the specified property's value is an array and the array does not contain any of value that equals the provided value or satisfies the provided expression.
  • limit(count,start,maxCount) - Returns the given range of objects from the result set
  • and(<query>,<query>,...) - Applies all the given queries
  • or(<query>,<query>,...) - The union of the given queries
  • eq(<property>,<value>) - Filters for objects where the specified property's value is equal to the provided value
  • lt(<property>,<value>) - Filters for objects where the specified property's value is less than the provided value
  • le(<property>,<value>) - Filters for objects where the specified property's value is less than or equal to the provided value
  • gt(<property>,<value>) - Filters for objects where the specified property's value is greater than the provided value
  • ge(<property>,<value>) - Filters for objects where the specified property's value is greater than or equal to the provided value
  • ne(<property>,<value>) - Filters for objects where the specified property's value is not equal to the provided value
  • rel(<relation name?>,<query>) - Applies the provided query against the linked data of the provided relation name.
  • sum(<property?>) - Finds the sum of every value in the array or if the property argument is provided, returns the sum of the value of property for every object in the array
  • mean(<property?>) - Finds the mean of every value in the array or if the property argument is provided, returns the mean of the value of property for every object in the array
  • max(<property?>) - Finds the maximum of every value in the array or if the property argument is provided, returns the maximum of the value of property for every object in the array
  • min(<property?>) - Finds the minimum of every value in the array or if the property argument is provided, returns the minimum of the value of property for every object in the array
  • recurse(<property?>) - Recursively searches, looking in children of the object as objects in arrays in the given property value
  • first() - Returns the first record of the query's result set
  • one() - Returns the first and only record of the query's result set, or produces an error if the query's result set has more or less than one record in it.
  • count() - Returns the count of the number of records in the query's result set

JavaScript Modules

rql/query

var newQuery = require("rql/query").Query();

This module allows us to construct queries. With the query object, we could execute RQL operators as methods against the query object. For example:

var Query = require("rql/query").Query;
var fooBetween3And10Query = new Query().lt("foo",3).gt("foo",10);

rql/parser

var parsedQueryObject = require("rql/parser").parseQuery(rqlString);

If you are writing an implementation of RQL for a database or other storage endpoint, or want to introspect queries, you can use the parsed query data structures. You can parse string queries with parser module's parseQuery function. Query objects have a "name" property and an "args" with an array of the arguments. For example:

require("rql/parser").parseQuery("(foo=3|foo=bar)&price=lt=10") ->
{
	name: "and",
	args: [
		{
			name:"or",
			args:[
				{
					name:"eq",
					args:["foo",3]
				},
				{
					name:"eq",
					args:["foo","bar"]
				}
			]
		},
		{
			name:"lt",
			args:["price",10]
		}
	]
}

Installation

RQL can be installed using any standard package manager, for example with NPM:

npm install rql

or CPM:

cpm install rql

or RingoJS:

ringo-admin install persvr/rql

Licensing

The RQL implementation is part of the Persevere project, and therefore is licensed under the AFL or BSD license. The Persevere project is administered under the Dojo foundation, and all contributions require a Dojo CLA.

Project Links

See the main Persevere project for more information:

Homepage:

Mailing list:

IRC: