2013-05-13 18 views
6

Ho un indice composito di due proprietà su un objectstore indexeddb e desidero recuperare un cursore in base all'intervallo di entrambe queste proprietà.Intervalli di cursori DB indicizzati su proprietà multiple

Ecco un oggetto esempio nel negozio:

{species: 'Oak',xcoord: 123456, ycoord: 654321} 

e l'indice:

treeStore.createIndex("treelocation", ["xcoord","ycoord"], { unique: false }); 

La creazione dell'indice è successo e posso vederlo in strumenti di sviluppo Chrome, ma ora mi piacerebbe piace aprire un cursore con un keyrange su entrambe le coordinate xey (che sarà l'estensione di una mappa).

Ricerca in linea Non riesco a vedere come eseguire questa operazione e l'apertura di un indice con una serie di intervalli di chiavi non sembra funzionare.

Grazie

Andrew

+0

hai provato 'IDBKeyRange.bound ([lowX, Lowy], [highX, highy])'? Solo una supposizione selvaggia. –

+0

Grazie Meryn - è stato così, se vuoi postare una risposta, posso accettarlo. – kes

+0

Hmmm deve essere il mio giorno fortunato! :) Ho pubblicato la soluzione come risposta. –

risposta

6

Mi è stato detto che la soluzione è effettivamente IDBKeyRange.bound([lowX,lowY],[highX,highY]).

+3

Questo non si comporterà come ci si potrebbe aspettare. L'intervallo 'IDBKeyRange.bound ([2,2], [4,4])' include valori come [3,0] e [3,5] come [2,2] <[3,0] <[ 3,5] <[4,4] per la definizione di chiavi (https://w3c.github.io/IndexedDB/#key-construct) In altre parole, è necessario eseguire ulteriori filtri, in quanto la soluzione da sola è insufficiente. per esempio. se la chiave [x, y_less_than_min] è vista, ignorala e avanza il cursore con 'continue ([x, lowY])'; se viene visualizzata la chiave [x, y_greater_than_max], ignorala e avanza il cursore con 'continue ([x + 1, lowY])' –

4

L'indice si è creato è un indice composito. Si tratta di query come questa:

index = objectStore.index('treelocation'); 
index.get([123456, 654321]); 

In alternativa, è possibile utilizzare due indici per ogni coorrd. Secondo me è meglio.

x_index = objectStore.index('xcoord'); 
y_index = objectStore.index('ycoord'); 
x_species = x_index.get(IDBKeyRange.only(123456)) 
y_species = y_index.get(IDBKeyRange.only(654321)) 
species = x_species.intersect(y_species); // this is result 
+1

Grazie Kyaw - questa sarebbe un'ottima soluzione se io volevo solo recuperare i record in una posizione, tuttavia xey sono le coordinate geografiche e sto cercando di recuperare un intervallo di entrambi come si ottiene, quindi l'indice composito. – kes

1

Il suggerimento di intervallo è parte della risposta, ma anche con i tasti di matrice è davvero solo un intervallo 1-dimensionale, non una selezione bidimensionale (o N-) dei dati. Con il vostro schema corrente è necessario fare qualcosa di simile:

index.openCursor([lowX, lowY], [highX, highY]).onsuccess = function(e) { 
    var cursor = e.target.result; 
    if (!cursor) return; // done! 

    var x = cursor.key[0], y = cursor.key[1]; 
    // assert(lowX <= x && x <= highX); 
    if (y < lowY) { 
     cursor.continue([x, lowY]); 
    } else if (y > highY) { 
     cursor.continue([x + 1, lowY]); 
    } else { 
     processRecord(cursor.value); // we got one! 
     cursor.continue(); 
    } 
}; 

(se coordinate non sono parte integrante, sostituire + 1 con un epsilon appropriato)

ho postato un esempio di una soluzione generalizzata a :

https://gist.github.com/inexorabletash/704e9688f99ac12dd336

Problemi correlati