realm / realm-swift

Realm is a mobile database: a replacement for Core Data & SQLite
https://realm.io
Apache License 2.0
16.22k stars 2.14k forks source link

Support of keypath sorting for to-many relationships #4554

Open Taco55 opened 7 years ago

Taco55 commented 7 years ago

Sorting is greatly improved in Realm 2.2.0 with keypath sorting for to-one relationships.

I was just wondering whether keypath sorting for to-many relationships will be supported in a future release as well? It would be great when it would be possible to sort like: dogOwners.sorted(byKeyPath: "dogs.last.age")

marchy commented 7 years ago

DEFINITELY demanded.

It's great that you guys took the single-relationship option but we just swept our codebase and in fact all our sorting use-cases are "to-many" scenarios (and thus have to do them out of Realm / custom).

For example, our list of conversations is sorted by the last unread message. To achieve this you need to sort using SortDescriptors of first "unread messages" (this is a subquery), then secondly by "messages.sentAt".

Would sorting by SUBQUERY be yet another feature request or be handled in this 'to-many' scenario?

rex-remind101 commented 7 years ago

👍

bdash commented 7 years ago

Sorting via to-many relationships is more complicated than to-one because you're now sorting via a computed value rather than directly on a property of an object. This requires having some way to represent an expression that computes the value to sort on, and some way to evaluate such expressions. Currently the more general expression evaluation is tied into query evaluation and cannot easily be used for sorting.

marchy commented 7 years ago

@bdash Makes sense in terms of the complexity needed. The manual version for such a computed property, for example: var userCuriosity:EventCuriosity? { return from( curiosities ).singleOrNil{ $0.person.id == User.currentUserPersonID } }

However the problem with not supporting such scenarios is that it makes the whole Realm architecture extremely fragely. We've had to compartmentalize Realm one refactor at a time to something that "can't do too much damage". The moment you can't use Realm filtering to store collections in its Results/Lists abstractions, you can't do fine-grained change notifications and need a custom mechanism there. Then you do that, you realize you can't communicate across threads – need to further compartmentalize there. Suddenly you need to hand-build everything because something is seen as "complex" and not supported, instead of rolling up the sleeves, tackling it, and understanding that without it you will not have partners succeeding on the platform.

Therefore I see this as absolutely critical for Realm to live up to its mission. Otherwise you have to re-architect your whole app (we have now twice) to get rid of Realm – making it very hard to re-architect again in its favour just to assess whether "it's now ready yet" – then discover it isn't.

Is there a solution where we could provide an arbitrary block to use for the sorting (this is also a scenario that's super critical). The trade-off could be sorting performance – FINE – but at least you could maintain the architecture desired for Realm to "take over" and model things the way you guys want them modelled. Re-architecture costs shouldn't be trivialized. You can launch any number of iterative features but if people can't add them on because they have been forced to architect in a different direction you will never have the adoption you need to make the features be used.

Points and cases:

These features should be set as P1's, above launch of hip "synching platforms" and all the other stuff the team's been working on lately (perhaps at the pressure of VC funding screaming down monetization down everyone's throats). An ORM, sync platform and enterprise services that are all Proof of Concept level across each pillar is much worse than having a single, battle-tested, production-level mature pillar that WORKS.

Want you guys to achieve the vision as much as you do! But priority of tackling these things makes ALL the difference. Hope to see a change in this strategy guys! :)