Hive: Sort question

Created on 24 Jan 2020  路  14Comments  路  Source: hivedb/hive

Hi, I try to put some element into Hive box by using putAll having a Map and all work fine. My problem is that if I try to get an item by method getAt I see that the element are sorted by key and not by indices. The is a way to sort a box by index and not by key?

question

Most helpful comment

I have the same issue,
I would like to group items by datetime while items are stored with uuid as key in box.

All 14 comments

Could you explain what you mean exactly? Boxes are sorted by lexicographically by key. Keys can either be strings or integers.

I want to insert into a box some elements:

{key: "456", value: any},
{key: "123", value: any},
{key: "789", value: any},

and I need to get it by position and not by key.
If I use getAt(0) I need to be returned {key: "456", value: any} and not {key: "123", value: any}

You can either change the keys or provide a custom keyComparator when you open the box.

Could you explain why you need this?

Edit: Maybe you want to use box.add() it automatically uses auto-increment keys

So I want to use hive to handle my remote data fetched from a server. No when I send a fetching request my server return a sorted data by description with a string key. Now I use a box with ValueListenable to handle my ListView and into the ListView I use builder and I get the hive object by method getAt() using the listview builder index. It's true that my hive object is cleaned on each remote request.

I try also to get key by using keyAt() method. But this method return always same key value and not key at index.

I think that the keyAt method must return the specified key at index position and not sorted by key.
If I add some object at specified index by putAt() method with index 5, when I getAt(5) the result must be the same and not sorted by keys, and I believe it is so currently. But the problem come when I try to use putAll method with a mapped items with key, in this case the index is lost and data in mapped items is sorted by key.
Now I cannot use putAt method because the listening event is fired for each item putted into the Hive. With putAll all is more fast.

I think you should take another look at the auto increment and indices documentation. Boxes are sorted by key. If you call box.putAt(index, value), Hive will get the key at the specified index and store the value under this key. When you then call box.getAt(index) you get the value.

The putAll() method associates all the keys in the given map to their values in Hive. This has nothing to do with indices. Maps do not have indices and most maps don't even have a stable order.

I think that the keyAt method must return the specified key at index position and not sorted by key.

What do you mean by "index position"? Indices are defined by the keyComparator which by default sorts keys lexicographically.

Hi I'm joining the conversation here for anyone that is wondering how to store the data without the auto-sorting in lexicographically you just need to set keyComparator to return 1 like this:

_box = await Hive.openBox('history',
          keyComparator: (dynamic k1, dynamic k2) => 1);

They will now be stored as you store them

Edit : I have spoken too hastily, now when I try to get a key it return null everytime

Box box = await HistoryDB.box;
    for (String _uuid in box.keys) {
      print(box.keys);
      print(box.get(_uuid));

return

I/flutter (13544): (M7sdsLPyCd7HqQ==, M7sdsLPyCd7HqQ==)
I/flutter (13544): null

I am facing the same problem. I have a list of items fetched from API, with UUID as each item's ID. I want to get my items sorted by date since UUID is not sortable.

I have the same issue,
I would like to group items by datetime while items are stored with uuid as key in box.

I have the same Issue! Also I can not understand why the approach of @RomanJos does not work.

I did the following to open and sort the list according to the sequence of insertion:

await Hive.openBox<Beehive>('beehives', keyComparator: (dynamic k1, dynamic k2)=>1);

This is how I add an item:

Box<Beehive> beehiveBox = Hive.box<Beehive>('beehives');
              String key = UniqueKey().toString();
              beehiveBox.put(key, Beehive(controller.text, key));

But the issue is that this code block:

print(beehiveBox.keys.toString());
beehiveBox.toMap().forEach((key, value) {
      print(key);
      Beehive b = beehiveBox.get(key);
      print(b);
}

Results in this output and error:

I/flutter (10933): ([#18156], [#6269b], [#f80dd], [#37945], [#0e665], [#7cc19], [#b4ead], [#89781])
I/flutter (10933): [#18156]
I/flutter (10933): null

I've been completely working around the problem, by sorting the values before using them.

I have a box with a model that consist of many fields and one of them is id of type String (UUIDV4). As I just need the keys for putting/deleting/adding I don't really use the sort order of the keys or the putAt, getAt, deleteAt functions with the index positions of the keys. I'm just using a sorted list of my values. If I need to CRUD I'm just using the get, put, delete with the id field.

var items = box.values.toList();
 items.sort((a, b) => a.name.compareTo(b.name));


@HiveType(typeId: 1)
class CategoryModel extends HiveObject {
  @HiveField(0)
  String id;

  @HiveField(1)
  String name;

  //...

  CategoryModel(this.id, this.name);
}

Tenho resolvido completamente o problema, classificando os valores antes de us谩-los.

Tenho uma caixa com um modelo que consiste em v谩rios campos e um deles 茅 id do tipo String (UUIDV4). Como eu s贸 preciso das chaves para colocar / excluir / adicionar, eu realmente n茫o uso a ordem de classifica莽茫o das chaves ou as fun莽玫es putAt, getAt, deleteAt com as posi莽玫es de 铆ndice das chaves. Estou apenas usando uma lista classificada de meus valores. Se eu precisar do CRUD, estou apenas usando get, put, delete com o campo id.

var items = box.values. toList ();
 Itens. sort ((a, b) => a.name. compareTo (b.name));


@HiveType (typeId :  1 )
 classe  CategoryModel  extends  HiveObject {
   @HiveField ( 0 )
   String id;

  @HiveField ( 1 )
   Nome da string ;

  // ...

  CategoryModel ( este .id, este .name);
}

this is not working in 2.0 :( I have a list of items and I want to sort by date

I don't know how much my solution can help others. But I had a similar issue where I wanted to sort the entries by date. So what I did was extract the dates in the yyyy-mm-dd format as a string, then created a random key using UUID. No two entries would be the same when we concatenated both strings and used it as a key. Now we can insert the value as Hive.boxes('data').put(generated key,valueToBeStored). So after insertion, the values are sorted as keys, so they will be formated date-wise. This may not be a permanent solution just a quick hack. I'm open to comments.

var day=entry.fullDate.day.toString().padLeft(2, '0'); var month=entry.fullDate.month.toString().padLeft(2, '0'); var generatedKey = month+day+entry.name+uuid.v4(); Hive.box('data').put(generatedKey,entry);
Note : I needed only sorting via month and day so please add year to the code if required.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

SergeShkurko picture SergeShkurko  路  4Comments

yannickvg picture yannickvg  路  4Comments

juandiago picture juandiago  路  4Comments

sergiyvergun picture sergiyvergun  路  4Comments

rupamking1 picture rupamking1  路  3Comments