Я храню большое количество небольших объектов в IndexedDB. Я хотел бы предоставить пользователю возможность экспортировать один из хранилищ объектов в файл, который они могут "загрузить".
Я прочитал эту статью в блоге. Который описывает чтение данных, JSON.stringify
ввод данных, кодирование его с помощью encodeURIComponent
и размещение его как href
для ссылки, которую они могут использовать для загрузки данных. Что-то вроде этого:
var transaction = db.transaction([objectstore], "readonly");
var content = [];
var objectStore = transaction.objectStore(objectstore);
objectStore.openCursor().onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
content.push({key:cursor.key,value:cursor.value});
cursor.continue();
}
};
transaction.oncomplete = function(event) {
var serializedData = JSON.stringify(dataToStore);
link.attr("href",'data:Application/octet-stream,'+encodeURIComponent(serializedData));
link.trigger("click");
};
Это хорошо, за исключением того, что в хранилище объектов будут миллионы записей, и я не чувствую, что это будет достаточно эффективно. Есть ли способ более прямо разрешить пользователю сохранять хранилище объектов в виде файла (таким образом, я могу снова импортировать его через веб-страницу).
Изменить Из некоторых заметок в комментариях я немного переписал, как это работает, чтобы получить от него немного больше сока. Новый код похож на:
var transaction = db.transaction([objectstore], "readonly");
var objectStore = transaction.objectStore(objectstore);
objectStore.getAll().onsuccess = function(evt) {
var url = window.URL.createObjectURL(new Blob(evt.target.results, {'type': 'application/octet-stream'}));
link.attr('href', url);
link.trigger('click');
};
Который даст мне результаты, такие как:
- 10 тыс. записей, среднее время экспорта 975,87 м.
- 100 тыс. записей, среднее время экспорта 5 850,100 м.
- 1mil records, 56,681.00ms среднее время экспорта
Как вы можете видеть, 1 миллион записей занимает около минуты, чтобы экспортировать. Есть ли лучший способ сделать это? (Я также попытался использовать курсор вместо .getAll()
, но курсоры медленнее)