-
-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Order parent by child's column (for to-one mapping) #1414
Comments
For ordering an embedded resource, the syntax is like: GET /site?select=*,address(*)&address.order=name Does that do what you want? |
I am sorry that I didn't make my intention clear. By ordering parent, I mean "ordering parent", not ordering the embedded resource. As one site can refer one and only one address, sorting the addresses belong to one site is meaningless. Explicitly, I want
rather than
|
I see what you mean. Perhaps this could be arranged for many-to-one embeds(we currently don't detect one-to-one's). Not sure about the query string syntax but this sql could be generated: -- projects >- clients (many-to-one)
-- enhacing the generated query from:
-- curl localhost:3000/projects?select=*,clients(*)
SELECT
"test"."projects".*,
row_to_json("projects_clients".*) AS "clients"
FROM "test"."projects"
LEFT JOIN LATERAL(
SELECT "test"."clients".*
FROM "test"."clients"
WHERE "test"."projects"."client_id" = "test"."clients"."id") AS "projects_clients" ON TRUE
ORDER BY projects_clients.name; |
IMHO, the query string could be |
This is something that I need as well. I would like to sort the parent by some column of the 1-to-1 embedded resource. I would use this query syntax, because it the same as the
When I tried the above, Postgrest 6.0.2 returns:
|
I wonder if the syntax should stay the same as always: GET /projects?select=*,clients(*)&clients.order=name Because since projects-clients is many-to-one, ordering the embedded clients as we do now is useless since they will always contain one element. |
Parentheses would be better(since GET /projects?select=*,clients(*)&order=clients(name.asc,rank.desc) Since that would allow ordering on multiple columns of the embedded table. |
By
I wonder if parentheses work well with some cases, say, how do we order parent by a mixture of columns from different levels? select ... from ...
order by projects_clients.name, project.name, projects_clients.rank desc I think it could be expressed easily as |
I know this is breaking, but instead of wrapping everything in parentheses, I'd like something like this more: GET /projects?select=*,clients(*)&order=clients.name,name,clients.rank!desc |
@Iced-Sun I think it should be like:
That's more consistent and seems similar to the way we do In general, I've been avoiding using PostgreSQL dot notation( |
Using pg dot notation opens up a door for having a very hard to read(and type) |
I see the point. As far as I am aware, the dot notation has several usages in Postgrest:
The parentheses have different semantics, either:
It seems to me that both
That said, I think both notations are acceptable. After all, they are not that different from an end-user's view. |
I didn't think of that. Do you mean that if It is indeed hard to read, and Regarding the implementation for ordering/filtering parents by child columns, considering the following request
obviously we need the child columns of To support the above functionality, a query may be generated as SELECT "projects"."name",
"projects_clients"."clients"
FROM "projects"
LEFT JOIN LATERAL (
SELECT
-- the result column
json_build_object('name', "clients"."name") as "clients",
-- the filtering columns
"clients"."validity", "clients"."rank",
-- the ordering column
"clients"."rank2"
FROM "clients"
WHERE "clients"."project_id" = "projects"."id"
) AS "projects_clients" ON TRUE
WHERE (
"projects_clients"."validity" && '[2021-12-01,2021-12-05)'::unknown
AND "projects"."name" = 'TopProject'::unknown
AND "projects_clients"."rank" > '1'::unknown
) ORDER BY "projects_clients"."rank" DESC, "projects"."name"; There is one concern that I am aware of now. Considering the following requests:
1 & 3 are filtering in the child level, and returning all parents independ on the child filters; while 2 are filtering in the parent level, and returing only parents that filtered by the child filters. One can add a filter of A bit confusing, right? |
That's true, parentheses are not consistent.
Note that this isn't really "our" syntax, as it is pg notation for ranges. It could also be
IIRC, the idea of using parentheses was temporary here, but it stayed like that. Now we're trying to provide an
I think that was a mistake, we could have done it like
Yes, grouping is what parens should be used for. In a way
So from the above, this would still be somewhat consistent to grouping since a regular I was also thinking we could do pg dot notation with a different operator, like
Related to the syntax proposed for composite type filtering #1543 (comment) |
Yes.
No. It's more like When using a child's column at the parent level for either filtering or ordering, it's not about "grouping", but about "accessing" child members. There are multiple different ways in PostgreSQL to access different kind of nested fields, of which only some are implemented right now in PostgREST:
Taking a step back for a second: Once we agree on a syntax for how to pass the child column in the parent level order param in the query string - what will we have to do with it in the query? Since we're only dealing with aggregated json documents from embedding, we'd have to implement it as a Why don't we just use I suggest the following:
Since we're serving JSON documents in the end, we can as well use operators that rely on that. We'd only have one syntax for accessing fields in |
I haven't yet tried the queries, but if it'd be done with the arrows then I fully agree, that keeps things consistent.
Wait, is this one an alternative to the |
Yes, you could:
But, in both cases the column needs to be selected in the I think the |
Just to clarify, the above ORDER would not work because the JSON is not available at that level but it can be done as mentioned above.
An option would be having an empty embed might as suggested on #2340 (comment). Overall the arrow looks better than GET /projects?select=*,clients()&clients->name=eq.nombre&order=clients->name It would also save the need to reinvent the hint syntax on an |
This is more or less working on #2511 but I think there could be trouble with the operator since it's ambiguous with the arrow json operators. In theory this special arrow operator could be extended to go down multiple levels(if all the embeds are to-one relationships)
Looking at the order param, Considering this special arrow operator has multiple uses:
It would be good to have a unambiguous syntax for it, this will also simplify the implementations. How about:
|
Hm, both What about a syntax that is closer to embedding?
|
Yeah, I think that's the best option. Iced-Sun also proposed the same above for the For I'm having trouble coming up with a name for this feature. We already have "embedded filters", what should we call these? I think the previous "embedded filters" section should have been called "filtering embedded resources" - only filters embedded resources and not the top/parent resource. If I rename it then
Could be called "embedded order"
"Embedded filters"
"Embedded conditionals" |
I think we should keep the |
Instead of 3 names for 3 features, how about only 1 feature - accessing embedded values in a "higher" context? How about calling that something like "lifting", "hoisting", "elevating" or "promoting"? And then give examples how to do that in the 3 different contexts. |
I'm thinking of calling these features "related orders"/"related filters"/"related conditions". "related" seems more apt and consistent. Not seeing a better name for now. |
In terms of "embedding relations", we now have "embedded filters" and "related filters", "embedded orders" and "related orders" and so on. I actually like it. "embedded filter" implies that the filter itself is embedded ("inside"), too. "related filter" implies that the filter is not only working on the current table's data, but also on other, related tables. Both have a good connection to "embedding relations". Only that "embedding relations" is currently called "embedding resources" or "resource embedding". Hm. Anyway I like the "related". |
I also had some some thoughts about this while thinking of refactoring the ApiRequest type. Right now we have two type of resources: relations(collections of resources) and functions(which are a REST resource, as discussed on #1086 (comment)) If we allowed embedding a relation with a function(which should be possible in theory), then we could call the feature "resource embedding" but truly we only have "relation embedding". So to rename "resource embedding" to "relation embedding" I think we'd have to clarify our REST design on the docs. |
Environment
Description of issue
I want something like
GET /site?select=*,address(*)&order=address.name
. Is that possible?The text was updated successfully, but these errors were encountered: