I'm always asking myself, why there is no language-independent standard for this to translate into SQL / LIST querying or processing and why this is almost never done in a kind of lisp-ish style to have a fast, compact, simple and easy parser...
(OR
(IN id (list 1 2 3))
(LTE createDate "2025-08-27")
)
I recently experimented with something like this and ended up going with MongoDB style queries (and field:operator:value syntax for a CLI wrapper)[1] as they are very powerful for nested/array operations and easy to parse everywhere but WAY more verbose than the syntax you chose for filterql! which also seems easy to understand for less technical folks.
Love the project, do you plan on supporting nested values?
I myself made a simple query language out of necessity. My key-value CRDT store [1] needed some syntax for basic queries.
It was strictly minimalistic, like {type:fruit} would produce [{type:fruit name:banana}...] and so on. When I think how to evolve it I lean towards adding lisp-like expression support. Cause I have a small lisp readily available.
I wonder if there is a good birds-eye FAQ/HOWTO/overview of all the existing (families) of query languages. Just to systematize Datalog, GraphQL, SQL, there are tons of them.
I see a mismatch between the library API `filter` vs the supported operator `| SORT rating desc"`. You could use the API to your advantage by separating concerns: add a new `.sort("fieldName")` method.
If adding helper methods for semantics and clarity is not the intent of the library, then I'd rename the `filter` method since it doesn't communicate the intention clearly.
The function executes a full pipeline filter expression + `|` operations like `SORT` and `LIMIT` (not just a predicate filter). So for instance naming it to `query` will match your README terminology and grammar (`query := filter | operation*`)
Hmm, maybe I need to think about this more, but since operations are a language feature (and could have any name, see custom operations), I don't think they could be attached to the filterql class like that.
You're right though, the naming of the `filter` method is confusing. I need to split off the filtering and applying of operations into two separate methods. And probably provide an additional `query` method like you said which would do what `filter` is doing now. Appreciate the feedback!
Any plans on this supporting JSONSchema? Seeing as most/all popular TypeScript validation libraries, which will likely be used to define the shape of the data, support converting to JSONSchema now?
I like it! It’s nice offering a little DSL in various spaces. Curious where you’re plugging it in?
Any intended support for collections/sets? In JQL is do ‘“foo” not in (“evil”, “silly”)’ or similar matchers over sets, like if tags are on a ticket or if tickets an in an N states
I've been using it in a CLI tool [1] to query media in my *arr services.
If you're talking about a query where you want "foo" to not be "evil" OR "silly", you could write 'foo != evil || foo != silly'.
There's a separate case where the value itself is an array/collection/set, in which case doing anything with that is currently unsupported. Values can only be strings, numbers, or booleans.
I thought about doing exactly what you suggested, where a query could access deeper properties with a syntax like "model.cost", but ultimately decided against it because I didn't like the complexity that would necessitate.
As for arrays, I usually opt for joining the string and then doing an "includes" query. e.g. ["sm", "md", "lg"] -> "sm,md,lg" and then you could write a query like "size *= md". Obviously this approach has its disadvantages though.
I'm definitely open to rethinking both of these if that's a common enough want/need.
Mainly because you might not always want to filter in-code. e.g. A CLI tool could take in a query as an argument, or a web app could allow a user to enter a query.
It offers nested filtering out of the box. All feature-packed in a lightweight package.
[1]: https://github.com/bouyguestelecom/spl [2]: https://github.com/BouyguesTelecom/SPL/blob/main/src/antlr/S...
[1]: https://github.com/nicolaspasqualis/go-fq
I wonder if there is a good birds-eye FAQ/HOWTO/overview of all the existing (families) of query languages. Just to systematize Datalog, GraphQL, SQL, there are tons of them.
[1]: https://github.com/gritzko/go-rdx
``` const recentGoodMovies = filterql .filter(movies, "year >= 2008") .sort("rating") .desc()
```
If adding helper methods for semantics and clarity is not the intent of the library, then I'd rename the `filter` method since it doesn't communicate the intention clearly.
The function executes a full pipeline filter expression + `|` operations like `SORT` and `LIMIT` (not just a predicate filter). So for instance naming it to `query` will match your README terminology and grammar (`query := filter | operation*`)
You're right though, the naming of the `filter` method is confusing. I need to split off the filtering and applying of operations into two separate methods. And probably provide an additional `query` method like you said which would do what `filter` is doing now. Appreciate the feedback!
Any intended support for collections/sets? In JQL is do ‘“foo” not in (“evil”, “silly”)’ or similar matchers over sets, like if tags are on a ticket or if tickets an in an N states
If you're talking about a query where you want "foo" to not be "evil" OR "silly", you could write 'foo != evil || foo != silly'.
There's a separate case where the value itself is an array/collection/set, in which case doing anything with that is currently unsupported. Values can only be strings, numbers, or booleans.
[1] https://github.com/adamhl8/inspectarr
As for arrays, I usually opt for joining the string and then doing an "includes" query. e.g. ["sm", "md", "lg"] -> "sm,md,lg" and then you could write a query like "size *= md". Obviously this approach has its disadvantages though.
I'm definitely open to rethinking both of these if that's a common enough want/need.