0

In my flutter project, I use box.query(myquery)..order(Kategoriak_.cikkcsoportnev).build(), but my Áramfejlesztők, szivattyúk category is at the end of the list.

How can I order it correctly, so Á would come after A, not at the end?

enter image description here

I am using objectbox: ^1.7.0

Ebadta
  • 317
  • 1
  • 3
  • 10

2 Answers2

1

I am also from Hungary :-)

I faced the same problem multiple times. My solution is that I store and update all search / order field values in the database without accents and converted to lowercase.

When I need to search and / or order, I use these duplicated fields and use the original fields to output the values.

I don't know objectbox, but in Firestore I use triggers to manage these duplicated fields when new documents are added or this field is modified.

As for removal of accents, I use this dart package which according to the sample in readme (removeDiacritics('árvíztűrő tükörfúrógép')) was more than likely written by someone who speaks Hungarian.

Peter Koltai
  • 8,296
  • 2
  • 10
  • 20
  • Hello Peti, It is ok, as a workaround, but I would like to see a solution for this problem. I don't think, it is intentional, that objectbox cannot order properly utf-8 strings. We need a fix for this, or maybe we need some settings? – Ebadta Jan 23 '23 at 13:53
  • As I wrote I am not familiar with this package, but there is an [open issue on GitHub](https://github.com/objectbox/objectbox-dart/issues/484) from last November stating this is currently not possible and offers the same work around in [this comment](https://github.com/objectbox/objectbox-dart/issues/484#issuecomment-1313342067). – Peter Koltai Jan 23 '23 at 14:22
  • Unfortunately it is common that you don't have the same configurability and localization support for these databases compared to having your own MySQL server for example. – Peter Koltai Jan 23 '23 at 14:24
  • Besides, if you had full support for Hungarian characters I am pretty sure it would treat `a` and `á` as different characters (as they are) and a possible user query of `aramfejlesztok` would not return `Áramfejlesztők` at all :-) – Peter Koltai Jan 23 '23 at 14:26
  • 1
    You wrote "objectbox cannot order properly utf-8 strings", but in fact this is a proper UTF-8 order. Check the character codes, `Á` is `c381` while `Z` is `5a`. That's why `Vágóeszközök` is after `Villamossági` which is also improper ordering (in Hungarian language). – Peter Koltai Jan 23 '23 at 14:30
0

I ended up implementing a short function using a Hungarian string array. It doesn't handle double and triple letters, but it's fine in most cases.

I didn't want to double my fileds, because I have a big database.

My solution:

  const List<String> hunABC = [
    "A", "a", "Á", "á", "B", "b", "C", "c", "D", "d",
    "E", "e", "É", "é", "F", "f", "G", "g", "H", "h", "I","i", "Í", "í", 
    "J", "j", "K", "k", "L", "l", 
    "M", "m", "N", "n", "O", "o", "Ó", "ó", "Ö", "ö", "Ő", "ő",
    "P", "p", "Q", "q", "R", "r", "S", "s", "T", "t", "U", "u", 
    "Ú", "ú", "Ü", "ü", "Ű", "ű", 
    "V", "v", "W", "w", "X", "x", "Y", "y", "Z", "z"
  ];
  

  int hunCompare(int num, int i, String input, int charNum) {
    if (num == -1)
    {
      if (input[charNum] == hunABC[i][0]) {
        return i;
      }

      return -1;
    }
    
    return num;  
  }

And my Comparable implementation for my class:

  @override
  int compareTo(Kategoriak other) {
    int otherNum = -1;
    int inputNum = -1;
    int charNum = 0;

    for (int i = 0; i < hunABC.length; i++)
    {
      inputNum = hunCompare(inputNum, i, cikkcsoportnev, charNum);
      otherNum = hunCompare(otherNum, i, other.cikkcsoportnev, charNum);

      if (i == hunABC.length) {
        if (inputNum == -1) inputNum = hunABC.length+1;
        if (otherNum == -1) otherNum = hunABC.length+1;
      }

      if (inputNum > -1 && otherNum > -1) {
        if (inputNum < otherNum) return -1;
        if (inputNum > otherNum) return 1;
        if (inputNum == otherNum) {
          if (cikkcsoportnev.length > charNum+1
          && other.cikkcsoportnev.length > charNum+1) {
            charNum += 1;
            inputNum = -1;
            otherNum = -1;
            i = -1;
          } else { return 0; }
        }
      }
    }

    return 0;
  }
Ebadta
  • 317
  • 1
  • 3
  • 10