JavaScript query language to perform complex object searches
github.com
github.com
[1] http://docs.mongodb.org/master/tutorial/query-documents/
- Conjunction and disjunction operations are defined by arrays in MongoDB, but as Objects in Queryl.
For example:
{ $or: [ { foo: { $gt: 100 } }, { bar: { $gt: 200 } } ] }
vs:
{ $or: { $gt: { foo: 100, bar: 200 } } }
- As you can notice in the above example, in MongoDB, you declare the property and the specific query inside, while in Queryl is the opposite: you declare the operation, and then the property.
- Of course, Queryl is still in it's infancy, and doesn't support as many operations as MongoDB does (but will be added eventually).
There are probably more differences that I'm not spotting due to lack of in depth knowledge in MongoDB queries.
var obj = minim.toElement({
a: 1,
b: [
{
c: 1,
d: 2,
e: [ { f: 5 } ],
f: 6
}
]
});
// Results are [5, 6]
var results = obj.find(function(value, key) {
return key.equals('f');
});
See https://github.com/refractproject/minimJSPath: https://github.com/dfilatov/jspath
JSONPath: https://github.com/s3u/JSONPath
(Since you don't have type safety in JS, I don't think you lose much by using strings, unless you want to wrap it in TypeScript.)
https://www-01.ibm.com/support/knowledgecenter/SS9H2Y_7.1.0/...
You could eliminate `$equal` and `$match` by looking for regex types and strings.
You could also take hints from Django and add operations to the keys to eliminate instantiating a new object for `$not`, `$gt` and `$lt`.
So, instead of:
queryl.match({
$or: {
$equal: {
foo: 'bar'
},
$and: {
$not: {
$match: {
foo: /^baz/
}
},
$gt: {
bar: 3
}
}
}, ...
...it would look like: queryl.match({
$or: {
foo: 'bar',
$and: {
foo__not: /^baz/,
bar__gt: 3
}
}, ...
Seems like this syntax is popular; is there something about this that doesn't work when serializing, or other uses that need the pure-object approach?Also, it had the edge case in which a user's object properties could collide with the operations defined by Queryl, which (I believe, didn't write tests for it) doesn't happen with the current approach.
Or if you really have to, using a sensible DSL to do the job instead?
Objects (or DSL) are easier to encode/decode than functions.
Also notice that Queryl is a very low level way of defining queries, and can easily become horrifying and unmaintainable with very complex queries.
The idea was to provide the low level, verbose way of defining this, and provide a user friendly frontend (as a DSL, probably) that compiles to it.
This kind of things looks better in homoiconic languages.
I'm wondering how that approach compares to rho/rewriting calculus.
Our use case for Queryl is to filter array of objects based on different criteria, but I guess an extra benefit is that the query language is completely decoupled from its usage, so anyone can use it in their own projects for different needs.
['contains?', ['list', 1, 2, 3], 1]
Instead of: {
$contain: {
foo: 1
}
}, {
foo: [ 1, 2, 3 ]
}Another benefit (which was the reason behind the implementation), is that we can stringify the search object to easily persist and share it, which would not be that easy with plain code.