2011-08-16 12 views
19

Хорошо, прежде всего, извините за мой английский.IndexedDB Fuzzy Search

Я работаю в веб-проекте, который показывает, когда я ввожу что-то в поле ввода, но я хочу использовать IndexedDB для улучшения скорости запросов в Firefox.

С WebSQL У меня есть это предложение:

db.transaction(function (tx) { 
    var SQL = 'SELECT "column1", 
        "column2" 
      FROM "table" 
      WHERE "column1" LIKE ? 
      ORDER BY "sortcolumn" DESC 
      LIMIT 6'; 

    tx.executeSql(SQL, [searchTerm + '%'], function(tx, rs) { 
    // Process code here 
    }); 
}); 

Я хочу сделать то же самое с индексированной и у меня есть этот код:

db.transaction(['table'], 'readonly') 
    .objectStore('table') 
    .index('sortcolumn') 
    .openCursor(null, 'prev') 
    .onsuccess = function (e) { 
    e || (e = event); 
    var cursor = e.target.result; 
    if (cursor) { 
     if (cursor.value.column1.substr(0, searchTerm.length) == searchTerm) { 
      // Process code here 
     } else { 
      cursor.continue(); 
     } 
    } 
}; 

Но слишком медленно, и мой код глючит .. Я хочу знать, есть ли лучший способ сделать это.

Благодарим за ответ.

ответ

20

Я, наконец, нашел решение этой проблемы.

Решение состоит в том, чтобы связать диапазон ключей между поисковым термином и поисковым термином с буквой «z» в финале. Пример:

db.transaction(['table'], 'readonly') 
    .objectStore('table') 
    .openCursor(
    IDBKeyRange.bound(searchTerm, searchTerm + '\uffff'), // The important part, thank Velmont to point out 
    'prev') 
    .onsuccess = function (e) { 
    e || (e = event); 
    var cursor = e.target.result; 
    if (cursor) { 
     // console.log(cursor.value.column1 + ' = ' + cursor.value.column2); 
     cursor.continue(); 
    } 
    }; 

Потому что мне нужно заказать результат, поэтому я определил массив до сделки, то мы называем его, когда мы загрузили все данные, как это:

var result = []; 
db.transaction(['table'], 'readonly') 
    .objectStore('table') 
    .openCursor(
    IDBKeyRange.bound(searchTerm, searchTerm + '\uffff'), // The important part, thank Velmont to point out 
    'prev') 
    .onsuccess = function (e) { 
    e || (e = event); 
    var cursor = e.target.result; 
    if (cursor) { 
     result.push([cursor.value.column1, cursor.value.sortcolumn]); 
     cursor.continue(); 
    } else { 
     if (result.length) { 
     result.sort(function (a, b) { 
      return a[1] - b[2]; 
     }); 
     } 

     // Process code here 
    } 
    }; 
+0

Спасибо большое! Это сократило его с 3500 мс до 140 мс для меня. – pimvdb

+0

@pimvdb Приятно знать, что вы сочли это полезным. Я добавил еще несколько примеров сортировки результата. –

+6

Лучше использовать '\ uffff' как ваш кинжал, а не z. Вы не получите результаты поиска, такие как «wikipædia» при поиске «wiki», если вы используете z ... –

3

Я экспериментировал с IndexedDB, и я нашел его очень медленным, добавив, что сложность его api и я не уверен, что его стоит использовать вообще.

Это действительно зависит от того, сколько данных у вас есть, но, возможно, стоит делать поиск в памяти, а затем вы можете просто сортировать и отключать данные из какого-либо хранилища, либо индексированногоDB, либо проще localStorage.

+0

Ну, похоже, что для Internet Explorer и Firefox я должен использовать простой XMLHttpRequest, потому что XHR + PHP еще быстрее. Было бы неплохо видеть, что WebSQL является стандартным, потому что таким образом клиенты будут использовать веб-приложения со скоростью и быть эффективными, а также сервер будет экономить ресурсы в долгосрочной перспективе. –

1

Я потерял ~ 2 часа по той же проблеме, и я нашел настоящую проблему.

Здесь решение:

  • Заменить IDBCursor.PREV на prev (это ужасно, но это решение)

IDBCursor.PREV прослушивается в данный момент на Chrome (26/02/2013)

+0

Ну, проблема у вас была не такая, как у меня. Ваша проблема вызвана изменениями в новой спецификации (обновлено 20 февраля 2013 г.): https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html. PS: Я только что обновил свою проблему и ответил, чтобы соответствовать новой спецификации. –