After reading here for ages, I've finally registered to ask a question. I've been messing around with IndexedDB lately and stumbled over a problem with compound indexes (I use them somilar to the example here).
I have an object in the objectstore with a string value, and a couple of integer values. E. g.:
[description:text, value1:int, value2:int, value3:int]
I created a compound index on this object like this:
("compoundIndex", ["value1" , "value2" , "value3"] , { unique: false });
In the html I got a couple of select boxes and a textfield, that allows the user to search for specific entries. The integers are passed as a keyrange to the opencursor-function on the index. Then I use indexOf(textfield) on the resulting set (like done here)
If the selectbox has a value, that value is used as upper and lower bound. If the select box is untouched, the lower range is 1 and the upper is a MAX_INT variable I declared (like described here).
sample code:
transaction = db.transaction(["schaden"] , "readonly").objectStore("schaden");
index = transaction.index("compoundIndex");
// keyrange-arrays from another function
lowerBound = [valueOneLower, valueTwoLower, valueThreeLower];
upperBound = [valueOneUpper, valueTwoUpper, valueThreeUpper];
range = IDBKeyRange.bound( lowerBound, upperBound );
index.openCursor(range).onsuccess = function(e){
var cursor = e.target.result;
if (cursor){
if (getTextfield.length == 0){
console.log("Entry found: " + cursor.value.description + ". Object: " + JSON.stringify(cursor.value));
}else if (cursor.value.bezeichnung.indexOf(getTextfield) !== -1){
console.log("Entry found: " + cursor.value.description + ". Object: " + JSON.stringify(cursor.value));
};
cursor['continue']();
};
};
I can search for entries perfectly well, when I have all values set in all the select-boxes. However, if I leave a field open, it messes up the search. Let's say I have not touched the value1-select box, and set the other boxes to 2, I'll get the lowerBound = [1,2,2] and the upperBound = [4294967295,2,2]. This will give me back all entries in my IDB, it doesn't take the 2nd and 3rd value into account.
Is this intended? Or is there a way around this? I have been searching for information about this over and over but seem to be in a dead end. My naive understanding of this API led me to believe it would take all array fields into account on the search. Since the object and therefor also the index I use are much more complex than the example above, performing searches on multiple indexes would be quite messy.
Thanks for your insights!
Edit:
To make it a little more clear after the first comments. Let's say if have the following object in the object store:
obj1 { val1 = 1 , val2 = 3 , val3 = 1 }
obj2 { val1 = 1 , val2 = 2 , val3 = 2 }
obj3 { val1 = 2 , val2 = 1 , val3 = 3 }
obj4 { val1 = 1 , val2 = 1 , val3 = 1 }
obj5 { val1 = 1 , val2 = 2 , val3 = 3 }
The index sorts it the way expected:
#1 [1,1,1] obj4
#2 [1,2,2] obj2
#3 [1,2,3] obj5
#4 [1,3,1] obj1
#5 [2,1,3] obj3
Let's assume now I search for the range (lower[1,1,1] , upper[1,1,1]) I'll get obj4. This is the behaviour when all select boxes have selected option 1.
Now if I search for an entry with val1 = 1, val2 = unknown and val3 = 1, I get the following range: lower[1,1,1] , upper[1,4294967295,1]. Expected results are obj4 [1,1,1] and obj1 [1,3,1]. Instead of these, the result is giving me 4 hits, namely obj4, obj2, obj5 and obj1 although val3 of obj2 and obj5 doesn't match the key range.
See Question&Answers more detail:
os