2011-08-16 26 views
19

Ok, antes que nada, perdón por mi inglés.IndexedDB Fuzzy Search

Estoy trabajando en un proyecto web que el programa sugiere cuando escribo algo en la casilla de entrada, pero quiero usar IndexedDB para mejorar la velocidad de consulta en Firefox.

Con WebSQL tengo esta frase:

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 
    }); 
}); 

quiero hacer lo mismo con IndexedDB y tengo este código:

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(); 
     } 
    } 
}; 

Pero no es demasiado lento y mi código tiene fallos .. Quiero saber si hay una mejor manera de hacer esto.

Gracias por su respuesta.

Respuesta

20

Finalmente encontré la solución a este problema.

La solución consiste en vincular un rango clave entre el término de búsqueda y el término de búsqueda con una letra 'z' en la final. Ejemplo:

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(); 
    } 
    }; 

Porque necesito para ordenar el resultado, por lo que he definido una matriz antes de la transacción, entonces nos llaman cuando cargamos todos los datos, así:

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

¡Muchas gracias! Esto lo redujo de 3500 ms a 140 ms para mí. – pimvdb

+0

@pimvdb Es bueno saber que lo encontraste útil. Añadí un ejemplo más sobre la clasificación del resultado. –

+6

Sería mejor usar '\ uffff' como su daga en lugar de z. No obtendrá resultados de búsqueda como "wikipædia" cuando busque "wiki" si usa z ... –

3

He estado experimentando con IndexedDB y he encontrado que es muy lento, sumado a la complejidad de su API y no estoy seguro de que valga la pena usarlo en absoluto.

Realmente depende de la cantidad de datos que tenga, pero potencialmente valdría la pena hacer la búsqueda en la memoria, y luego simplemente puede ordenar y quitar los datos de algún tipo de almacenamiento, ya sea indexedDB o el localStorage más simple.

+0

Bueno, parece que para Internet Explorer y Firefox tengo que usar un simple XMLHttpRequest, porque XHR + PHP es incluso más rápido. Sería bueno ver que WebSQL sea estándar, porque de esa forma los clientes utilizarán las aplicaciones web con velocidad y eficacia, y el servidor ahorrará recursos a largo plazo. –

1

He perdido ~ 2 horas en el mismo problema y he encontrado el problema real.

Aquí la solución:

  • Reemplazar IDBCursor.PREV por prev (que es horrible, pero esta es la solución)

IDBCursor.PREV hay micrófonos en el momento en Chrome (26/02/2013)

+0

Bueno, el problema que tienes no es el mismo que tuve. Su problema está causado por los cambios en la nueva especificación (actualizada el 20 de febrero de 2013): https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html. PD: Acabo de actualizar mi problema y mi respuesta para que coincida con la nueva especificación. –