2013-05-13 18 views
6

Mam złożony indeks dwóch właściwości w magazynie obiektów indexeddb i chcę pobrać kursor w oparciu o zakres obu tych właściwości.Indeksowane zakresy kursorów DB dla wielu właściwości

Oto przykład obiekt w sklepie:

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

i index:

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

Utworzenie indeksu jest udana i widzę go w narzędziach deweloperskich Chrome, jednak teraz ja jak otworzyć kursor z kluczem na obu współrzędnych x i y (który będzie zasięgiem mapy).

Wyszukiwanie w Internecie Nie widzę sposobu, aby to zrobić, a otwarcie indeksu z tablicą zakresów kluczy nie działa.

Dzięki

Andrew

+0

Czy próbowałeś 'IDBKeyRange.bound ([lowX, Łowy], [highX, chciałbym mocno])'? Po prostu dzikie domysły. –

+0

Dzięki Meryn - to było to, że jeśli chcesz napisać jako odpowiedź, mogę to zaakceptować. – kes

+0

Hmmm musi być moim szczęśliwym dniem! :) Postawiłem rozwiązanie jako odpowiedź. –

Odpowiedz

6

Powiedziano mi, że rozwiązaniem jest rzeczywiście IDBKeyRange.bound([lowX,lowY],[highX,highY]).

+3

Nie będzie się to zachowywać tak, jak można się spodziewać. Zakres "IDBKeyRange.bound ([2,2], [4,4])" obejmuje wartości takie jak [3,0] i [3,5] jako [2,2] <[3,0] <[ 3,5] <[4,4] za definicję kluczy (https://w3c.github.io/IndexedDB/#key-construct) Co oznacza, że ​​trzeba będzie wykonać dodatkowe filtrowanie, ponieważ samo rozwiązanie jest niewystarczające. na przykład jeśli widoczny jest klucz [x, y_less_than_min], zignoruj ​​go i przesuń kursor o 'continue ([x, lowY])'; jeśli klucz [x, y_greater_than_max] jest widoczny, zignoruj ​​go i przesuń kursor o 'continue ([x + 1, lowY])' –

4

utworzony indeks jest indeksem kompozytowych. Jest to zapytanie takie jak to:

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

Alternatywnie można użyć dwóch indeksów dla każdego wiersza. Moim zdaniem jest lepiej.

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

Dzięki Kyaw - byłoby to świetne rozwiązanie, jeśli chciał tylko odzyskać rekordy w jednym miejscu, jednak x i y są współrzędnymi geograficznymi, a ja chcę uzyskać zasięg zarówno w jednym, jak i w wyniku złożonego indeksu. – kes

1

Propozycja zasięgu jest częścią odpowiedzi, ale nawet w przypadku kluczy tablicowych rzeczywiście jest to tylko zakres 1-wymiarowy, a nie 2 - (lub N-) wymiarowy wybór danych. Z aktualnym schemacie musisz zrobić coś takiego:

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

(jeśli nie są integralną współrzędne wymienić + 1 z odpowiednim epsilon)

ja pisał przykład uogólniony Rozwiązaniem :

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