realm / realm-swift

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

Support case-insensitive string sorting #2970

Open dltlr opened 8 years ago

dltlr commented 8 years ago

Is it possible to get query results sorted in a case insensitive way so that: Cat (capital C) comes before cow (lower case c)?

Thanks

jpsim commented 8 years ago

That's not currently possible, but I've updated this ticket to track adding that functionality.

In the meantime, you could store a case-normalized version of the property you want to sort on in your model and sort on that.

dltlr commented 8 years ago

thank you

tschubotz commented 8 years ago

What comparator is realm using when sorting strings?

Let's assume, I have several objects that have the following value for the property name:

"hello"
~hello
hello
Hello
ello
éllo

When I sort these values, using realm, the order will be the following:

|hello
~hello
ello
Ello
éllo
hello
Hello

I do understand that the uppercase names will always be placed after their lowercase equivalent. That makes sense since the sorting is case sensitive.

However, I do not understand why |hello" and ~hello are sorted to the beginning and why éllo is not placed at the very bottom. I would expect that since this would be the order of their respective unicode codes.

simonask commented 8 years ago

@tschubotz Realm has limited Unicode awareness when sorting strings, which is to say that all strings are sorted according to an en_US.UTF-8 locale, and not UTF-8 encoded byte value order.

We are aware that this is lacking for a wide range of use cases, but a proper solution to string sorting (including case-insensitivity) requires quite sophisticated locale support, which is something we are still designing.

I hope that answers your question. :-)

rrrlasse commented 8 years ago

Sorting simply according to increasing unicode values would be very wrong in most countries. For example, there exists three symbols with unicode values Å = 197, Æ = 198, Ø = 216. However in the danish language you traditionally sort them Æ, Ø, Å.

Realm will sort unicode symbols 0...591 (upto and including Latin Extended 2) in the english ("en") locale. This gives the sorting order that you quoted, which is the correct order for most countries that have the letters "é" and "h" in their alphabet.

This method is not perfect, though. There are minor flaws for some letters in some countries.

Unicode symbols beyond Latin Extended 2 will be sorted simply according to their unicode value.

inPhilly commented 7 years ago

Wow, I am just switching to Realm today and this is kind of a big deal. Seems like I will have to store two of almost every property in my database. Has this changed at all since January of 2016?

Heki2017 commented 6 years ago

any progress on the topic since the question was raised in 2015?

bmunkholm commented 6 years ago

@Heki2017 Unfortunately not. We are not prioritizing features by the date they were created. Although this is something we surely would like to support there are (still) other bugs or features that are more requested for the time being.

trant commented 5 years ago

No case insensitive sorting, no custom sorting. These things should be pointed in your documents when someone is thinking of using it in a project. Its a flaw, own it and make sure people that wanna use it know it from day 1. You only find out when its too late already. Gotta hack some stuff now, great!

jadar commented 3 years ago

Any movement on this? It's been just over 5 years since this was opened. Not having a basic feature like this is pretty surprising. Foundation has localizedCaseInsensitiveCompare(_:). Seems like this should be the default string sort behavior anyways.

dante-teo commented 3 years ago

I was using LexoRank to sort my documents in FireStore, this is quite important for my project, any updates?

rursache commented 7 months ago

uh, still no realm-native lowercase sorting in 2024?

bdkjones commented 4 months ago

Good lord, this has been open for a decade.

 A `SortDescriptor` stores a key path and a sort order for use with `sorted(sortDescriptors:)`. It is similar to
 `NSSortDescriptor`, but supports only the subset of functionality which can be efficiently run by Realm's query engine.

If I may be so bold: a query engine that can't do case-insensitive sorting is a broken query engine. This is what Realm produces:

Adam
Bob
Susan
Vicky
allison

The only suggested workarounds are:

  1. Exponentially bloat your database size by storing a lowercased version of every single property you might want to sort.
  2. Drop the live Results collection in favor of Array. (Which, at that point, why not just drop Realm altogether?)

Great.

bdkjones commented 4 months ago

This is what developing with Realm often feels like. Imagine Realm is a car. It has:

  1. Full self-driving.
  2. Seats that massage your back.
  3. A top speed of 498mph.
  4. A gas tank that fills itself up automatically.

And:

  1. No reverse.

You: "How do I get it out of my garage?" Mongo: "Rope."

aehlke commented 4 months ago

Another option is to generate the index field in memory

Personally I added a grdb SQLite for full text search. But now I have two redundant storages.