Сортировать по и фильтровать по другому столбцу в хранилище объектов IndexedDB - PullRequest
0 голосов
/ 11 июня 2018

Допустим, у меня есть хранилище объектов с именем messages, структура которого выглядит как

{
    "id": id, 
    "from": from, 
    "conversation": conversation, 
    "time": time,
    "text": text
}

Где, кроме text, все является числом.

Если бы я хотелпрочитав разговор, я, естественно, получаю курсор, выполнив store.index("conversation").openCursor(IDBKeyRange.only(conversation)), но я также хотел бы, чтобы возвращаемые значения были отсортированы по time, как я могу это реализовать?

Еще, чтобы добавить, хранилище объектов имеетid как его первичный ключ, и чем больше id, тем больше time.

Ответы [ 2 ]

0 голосов
/ 12 июня 2018

Хм, может быть, попробуйте это:

function open() {
  return new Promise((resolve) => {
    const r = indexedDB.open('convos-by-time-test');
    r.onupgradeneeded = function(event) {
      const conn = r.result;
      console.debug('Creating database', conn.name);
      const store = conn.createObjectStore(
      'conversations', {keyPath: 'id', autoIncrement: true});
      store.createIndex('conversation-time', ['conversation', 'time']);
    };
    r.onsuccess = function(event) {
      resolve(r.result);
    };
  });
}

function addConversations(conn, convos) {
  return new Promise((resolve, reject) => {
    const txn = conn.transaction('conversations', 'readwrite');
    txn.oncomplete = resolve;
    txn.onerror = _ => reject(txn.error);

    const store = txn.objectStore('conversations');
    for (const convo of convos) {
      store.put(convo);
    }
  });
}

function findConversationOrderByTime(conn, conversation) {
  return new Promise((resolve, reject) => {
    const txn = conn.transaction('conversations');
    txn.onerror = _ => reject(txn.error);
    const store = txn.objectStore('conversations');
    const index = store.index('conversation-time');
    const lowerBound = [conversation, 0];
    const upperBound = [conversation, Number.MAX_SAFE_INTEGER];
    const range = IDBKeyRange.bound(lowerBound, upperBound);
    const request = index.getAll(range);
    request.onsuccess = _ => resolve(request.result);
  });
}

function deleteDatabase(name) {
  return new Promise((resolve) => {
    const request = indexedDB.deleteDatabase(name);
    request.onsuccess = resolve;
    request.onerror = _ => reject(request.error);
  });
}

async function runTest() {
  console.debug('Starting test');
  const conn = await open();
  console.debug('Connected to database');

  const data = [];
  data.push({'from': '123', 'conversation': 'a', 'time': 1});
  data.push({'from': '456', 'conversation': 'd', 'time': 4});
  data.push({'from': '789', 'conversation': 'b', 'time': 2});
  data.push({'from': '012', 'conversation': 'b', 'time': 1});
  data.push({'from': '345', 'conversation': 'b', 'time': 3});
  data.push({'from': '678', 'conversation': 'c', 'time': 3});

  await addConversations(conn, data);
  console.debug('Added initial test data of %d objects', data.length);

  const targetConversation = 'b';
  const results = await findConversationOrderByTime(conn, targetConversation);
  console.debug(
  'Matched %d conversations with conversation value %s', results.length,
  targetConversation);

  for (const result of results) {
    console.debug('Result:', JSON.stringify(result));
  }

  conn.close();

  await deleteDatabase(conn.name);
  console.debug('Deleted database');

  console.debug('Test completed');
}

Почему я думаю, что это работает, см. Мои другие ответы на вопросы о составных индексов

0 голосов
/ 11 июня 2018

Множество предположений о том, как вы сформулировали свой вопрос, было бы проще, если бы вы опубликовали какой-то код, который вы пробовали.

Я собираюсь предположить, что вы запрашиваете базу данных и получаете массив возвращаемых объектов

Примерно так (делая предположения о том, как хранится дата)

let conversation = [
  {"id": 1, "from":'from', "conversation":'conversation', "time": 1528735036499 },
  {"id": 3, "from":'from', "conversation":'conversation', "time":1528735087860},
  {"id": 4, "from":'from', "conversation":'conversation', "time":1528735111224},
  {"id": 2, "from":'from', "conversation":'conversation', "time": 1528735070207 }
]

let orderedConvo = conversation.sort((a, b) => a.time - b.time)

console.log(orderedConvo)

Вам следует использовать .sort () в вашем массиве и сравнить время, в настоящее время его сортировка самая старая - самая новая, если вы хотите, чтобы новыесамый старый, просто переключитесь на b.time - a.time

Я специально заказал идентификаторы 1-4, чтобы показать, как они должны быть упорядочены по времени.Вот кодеин с отсортированным результатом

https://codepen.io/anon/pen/yEMqxB?editors=0011

...