Есть ли способ сортировки с использованием составного/составного ключа в indexedDB?

В разделе Как использовать метод подсчета IndexedDB с составными ключами? Я научился фильтровать отдельные атрибуты. Пока все хорошо, но теперь мне нужно сортировать и фильтровать одновременно.

Мое хранилище объектов заполнено этими объектами:

os.put({feed_id:1,id:1,title:"foofoo",time:111});
os.put({feed_id:1,id:2,title:"foobar",time:112});
os.put({feed_id:1,id:3,title:"foobaz",time:113});
os.put({feed_id:3,id:1,title:"bazfoo",time:114});
os.put({feed_id:3,id:2,title:"bazbar",time:115});
os.put({feed_id:3,id:3,title:"bazbaz",time:116});
os.put({feed_id:1,id:4,title:"foofoo",time:122});
os.put({feed_id:1,id:5,title:"foobar",time:121});
os.put({feed_id:1,id:6,title:"foobaz",time:120});
os.put({feed_id:3,id:4,title:"bazfoo",time:119});
os.put({feed_id:3,id:5,title:"bazbar",time:118});
os.put({feed_id:3,id:6,title:"bazbaz",time:117});

У меня есть два индекса, установленных в хранилище объектов, один (idx_feedid) имеет keyPath feed_id, что позволяет мне получить все объекты с определенным идентификатором фида с помощью openCursor, а другой (idx_ts) с keyPath ["id","feed_id","time"].

Проблема в том, что повторение результатов idx_feedid дает мне результаты без упорядочивания временной метки. В SQL я бы легко сделал SELECT * FROM feeditems WHERE feed_id=3 ORDER BY time DESC, но как это сделать в IndexedDB?

И как я могу ограничить возвращаемые результаты для достижения нумерации страниц? По сути, мне нужно что-то вроде MySQL LIMIT 0,10/LIMIT 10,10/...


person Skynet    schedule 31.10.2013    source источник
comment
возможный дубликат в IndexedDB есть способ сделать отсортированный составной запрос?   -  person Josh    schedule 22.05.2014


Ответы (2)


Нельзя делать лимиты. Даже если вы попытаетесь это сделать, внутренние реализации используют оптимизации, которые вы не можете контролировать, например, всегда загружают первые 100 строк в ОЗУ, даже если вам нужна только 1. К счастью, это не слишком сильно влияет на небольшие приложения, потому что это все еще довольно быстро.

Что касается вашей проблемы, взгляните на https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore?redirectlocale=en-US&redirectslug=IndexedDB%2FIDBObjectStore#openCursor(). Настройте IDBKeyRange для идентификатора канала 3 и перейдите в направлении, например «предыдущий», чтобы выполнить итерацию в порядке убывания.

Изменить: для разбивки на страницы вы должны использовать cursor.advance(+ или - n строк)

person Josh    schedule 31.10.2013
comment
Может быть, вы также можете помочь мне с этим вопросом: дата - person John Smith; 24.10.2014

Используйте составной индекс, ['feed_id', 'time'] и запрос через IDBKeyRange.only([3]) в обратном направлении.

Используя мою библиотеку с открытым исходным кодом, можно сделать следующее:

var schema = {
  stores: [{
    name: 'os',
    indexes: [{
      name: 'feed_id, time',
      keyPath: ['feed_id', 'time']
    }]
  }]
}

var db = new ydn.db.Storage('db name', schema);
var kr = ydn.db.KeyRange.starts([3]);
db.values('os', 'feed_id, time', kr, 10, 0, true).done(function(values) {
  console.log(values); // sorted by descending of time
});

Библиотека поддерживает как indexeddb, так и websql без какой-либо зависимости. Вы также увидите очень высокую производительность на websql.

Если вы используете прокладку, составной индекс может работать неправильно.

person Kyaw Tun    schedule 01.11.2013