Skip to content

[Question] Sort by relationship attributes? #359

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

Closed
RKennedy9064 opened this issue Jul 30, 2018 · 9 comments
Closed

[Question] Sort by relationship attributes? #359

RKennedy9064 opened this issue Jul 30, 2018 · 9 comments

Comments

@RKennedy9064
Copy link

I've been working with JsonApiDotNetCore and EmberJS for a bit and everything has been working well so far, but I've run into something that I can't seem to find the answer for, so I figured I'd post here. On the JsonApi website it says

Note: It is recommended that dot-separated (U+002E FULL-STOP, “.”) sort fields be used to request sorting based upon relationship attributes. For example, a sort field of author.name could be used to request that the primary data be sorted based upon the name attribute of the author relationship.

Does JsonApiDotNetCore currently support this, or does it plan to in the future? I didn't see anything on the documentation related to this and I have some models that I'd like to be able to sort by using the relationship values. If it isn't currently supported, do you have any advice on how it might be possible to get it working in the current build? Any help would be greatly appreciated.

@joshhubers
Copy link
Contributor

Did you see issue #85 ?

@RKennedy9064
Copy link
Author

I just took a look at it and it seems similar, but not quite the same as what I'm trying to do. Currently my url looks like this.

/api/v1/sample-units?include=field-disposition&page[number]=1&page[size]=20&sort=field-disposition.label

while the issue referenced had a link of

bookings?include=status&filter[starting-at]=le:2017-01-01&filter[status.name]=eq:active

Where the relationship was inside of filter[status.name].

When I post to my url it returns "Attribute 'field-disposition.label' does not exist on resource 'sample-units'", Suggesting that sort is trying to look for an attribute by that name instead of a relationship. Is there a workaround to this, or perhaps a chance for JsonApiDotNetCore to support this in the future?

@jaredcnance
Copy link
Contributor

@RKennedy9064 yes it looks like we missed this. Currently, this logic was created for filters but should have been applied to sorting and sparse fieldsets as well. This is how it is done for filters currently:

public bool IsAttributeOfRelationship => Attribute.Contains(".");

if (filterQuery.IsAttributeOfRelationship)
return source.Filter(new RelatedAttrFilterQuery(jsonApiContext, filterQuery));
return source.Filter(new AttrFilterQuery(jsonApiContext, filterQuery));

So, we either use RelatedAttrFilterQuery or AttrFilterQuery, but frankly most of this could be extracted into a base AttrQuery and RelatedAttrQuery that is re-used for filtering, sorting and sparse fieldsets.

@RKennedy9064
Copy link
Author

@jaredcnance Yeah it would be nice to a base AttrQuery or something similar. The database I work with wasn't designed as nicely as I'd have hoped, so a lot of my models need to be sorted by attributes on other models. I just noticed you added the feature tag to this. does that mean it's something you'll be looking to implement into the current build?

@jaredcnance
Copy link
Contributor

jaredcnance commented Jul 30, 2018

@RKennedy9064 for me, my highest priority is validating and releasing 2.4.0 and this won't make that build. After that gets out, I'll be focusing on #39. Then I'll need to re-evaluate priorities and see where this fits. If you (or anyone for that matter) are interested in working on this feature, I can carve out some time to put together a design doc and would provide support on Gitter.

@RKennedy9064
Copy link
Author

@jaredcnance I'm not sure how much free time I currently have, but I'd be interested in tinkering around with it if some free time comes up in the next few weeks.

@milosloub
Copy link
Contributor

milosloub commented Sep 21, 2018

@jaredcnance I can make this work using base AttrQuery logic, that sounds good.
But OrderBy doesn't support nested queries as Include,so OrderBy("parent.nested") won't work.
There are two (or more) solutions:

  1. Use extension of library System.Linq.Dynamic.Core to easier nested sort handling like this:
           entities.OrderBy("parent.nested ASC", null);
  1. Make Expression builder which builds query based on level of nestedness:
    "firstname" -> entities.OrderBy(p => p.FirstName);
    "client.firstname" -> entities.OrderBy(p => p.Client.FirstName);

Which one do you prefer? Or do you have more ideas?

I have tried both, first one is really easy, but that dependency on System.Linq.Dynamic.Core doesn't seems good to me. With second one I thought that it's the same as Where predicate builder, but after some research it's more complicated to make it dynamic, but it's question of time to find the right approach.

@jaredcnance
Copy link
Contributor

@milosloub thanks for looking into this. I think I'd prefer to stick with Expression Trees for now. System.Linq.Dynamic.Core introduces an entirely new syntax structure we would need to map to. We can also perform our own optimizations since we know that some trees will be re-used (e.g. we can cache a tree for a given base entity + attribute path).

@milosloub
Copy link
Contributor

milosloub commented Sep 22, 2018

Ok, I'll start working on it on Monday

This was referenced Sep 24, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

4 participants