RFC: Simplified filtering API
See original GitHub issueA proposal for simplified filter
syntax for equality filters. The goal is to expand the scope of cardinality inference and provide a less verbose alternative to e.op(x, "=", y)
when specifying simple equality filters.
In e.select
, the filter
key should also accept a plain JS object. The keys can correspond to an property/link name and can point to singleton expressions or plain JS literals.
Current syntax
e.select(e.Movie, (movie) => ({
filter: e.op(movie.release_year, '=', '2008'),
}));
Proposed syntax
e.select(e.Movie, () => ({
filter: {release_year: 1999},
}))
It’s no longer necessary to include a reference to the scope variable movie
or write the e.op()
expression, which is one of the bits of query builder syntax that is hardest to type quickly and least conducive to autocompletion.
Type inference still works as expected. Filtering on a non-exclusive property returns an array:
e.select(e.Movie, (movie) => ({
title: true,
filter: {release_year: 1999},
})).run(client);
// {title: string}[]
If a referenced property/link has an exclusive constraint, the result will be a singleton.
e.select(e.Movie, (movie) => ({
title: true,
filter: {id: e.uuid('2053a8b4-49b1-437a-84c8-e1b0291ccd9f')},
}));
// {title: string}
This hold true for object-level exclusive constraints corresponding to a tuple of properties. (This is infeasible to implement using the e.op
formulation.) e.g. if there is a compound constraint on (.title, .release_year)
the following would be inferred to be a singleton.
// singleton
e.select(e.Movie, (movie) => ({
title: true,
filter: {
title: "A Star is Born"
release_year: 2018
}
}));
// {title: string}
An additional proposal is to support cardinality inference for “expression constraints”. e.g.
type Movie {
property title -> str;
constraint exclusive on str_lower(.title);
}
The constraint’s stored expr
would be introspected to support the following:
// singleton
e.select(e.Movie, (movie) => ({
title: true,
filter: {
'str_lower(.title)': 'a star is born',
},
}));
Non-exclusive
There is a question of whether the “object filter” syntax would support non-exclusive properties. @elprans objected to supporting this syntax exclusively for singleton/exclusive filtering. Filtering by equality on an exclusive vs nonexclusive property would look very different and possibly lead to confusion.
e.select(e.Movie, (,)=>({
filter: { id: "adsf" }
filter: e.op(m.rating, '=', 5),
}));
This proposal can be generalized to a way to specify any set of equality filters (https://github.com/edgedb/edgedb-js/issues/347)
e.select(e.Movie, ()=>({
filter: { rating: 5 } // non-exclusive prop
}));
This fixes the inconsistency, but makes it less visually obvious when a filter
clause corresponds to a singleton filter. It also increases implementation complexity, since we’ll need to statically determine whether keys of the “object filter” object correspond to an exclusive constraint, instead of simply checking if the value passed to filter
is an object literal.
Issue Analytics
- State:
- Created a year ago
- Reactions:10
- Comments:7 (2 by maintainers)
Top GitHub Comments
String IDs without
e.uuid
seems good IMO, might just want to clarify the deal with the string allowed to have / not have dashesIs there something blocking this from getting into EdgeDB?