4

Can anyone explain why my IDBKeyRange only seems to be filtering on the first column?

I have an index defined as follows:

osDrugs.createIndex("combined", ["name", "strength", "form", "packsize"], {unique: false});

My query is roughly as follows:

var transaction = pimsDB.transaction("drugs");
var objectStore = transaction.objectStore("drugs");
var range = IDBKeyRange.bound([tmpName, tmpStrength, tmpForm, tmpPack],[tmpName+"z", tmpStrength + "z", tmpForm+"z", tmpPack+"z"]);
var index = objectStore.index("combined");
var request = index.openCursor(range);

My results appear to be filtering from tmpName up to tmpName + "z" but completely ignoring the strength, form, and packsize.

Can anyone see what I'm doing wrong?

Oh, all fields are stored as strings....

Cheers,

Dan

ADDITIONAL INFORMATION:

Another table that I created with a composite index appears to be working. The only two difference between these tables are as follows:

1) The table that works only has 2 properties in the index. 2) In the table that works both properties are part of a 3 property primary key.

I've tested that it works on this table by using the "Resources" tab in Chrome which allows me to filter an index by the lower bound key and return data.

MORE ADDITIONAL INFORMATION:

After some more testing, and switching over to FF to make sure that it wasn't a chrome but I was experiencing I think I have found the problem. I don't believe searching that composite index works the way I was expecting...

The IDBKeyRange is actually a range... It appears that when I enter, for example,

["PARA","500","TAB","32"] ["PARAz","500z","TABz","32z"]

IndexedDB searches for the first drug that starts at the LB, and selects everything up to the last drug that ends at the upper bound.

This, I believe, is why it's managing to select strengths that start with any value. It's not actually filtering for strengths that start "500",it's selecting everything between the first instance of "500" on a drug up to the last.

If my assumption is correct, the following article is probably a bit wrong/misleading (as I believe the user wanted to search a rectangle and not a range:

Indexed DB cursor ranges on mulitiple properties

Can anyone confirm what I'm finding and tell me if there's a way I can actually search IndexedDB on multiple values? At the bottom of the article above, someone mentions an intersect function which I think would work but when I search online, it doesn't seem to exist...

Cheers,

Dan

Community
  • 1
  • 1
Daniel
  • 73
  • 2
  • 7
  • I just had same problem, and realized that problem was due one boundary array element was undefined. – Ante Feb 12 '14 at 22:27
  • Mine all have values for sure :( what browser are you using? How many fields does your composite index contain? – Daniel Feb 13 '14 at 00:15
  • I'm using Chrome 32, and two fields are in composite index. In my case index is store key {keyPath: ["obj_id", "date"]}. – Ante Feb 13 '14 at 08:19
  • have you read my article http://dev.yathit.com/ydn-db/nosql-query.html? which explain a bit of them. – Kyaw Tun Feb 17 '14 at 06:27
  • Where in the spec do I read up on a "combined" index? http://www.w3.org/TR/IndexedDB/#widl-IDBObjectStore-createIndex-IDBIndex-DOMString-name-DOMString-sequence-DOMString--keyPath-IDBIndexParameters-optionalParameters – buley Mar 12 '14 at 13:29
  • Yes, you are correct - an IDBKeyRange is a range, and the cursor will iterate over everything from the lower bound to the upper bound (a 1D range). That other article does appear incorrect - it's not going to be searching a rectangle as expected. I'll comment over there. – Joshua Bell Oct 06 '15 at 17:33

1 Answers1

6

I've posted a generalized solution over at:

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

The short summary is that you need to inspect each dimension of the result, and if any value is beyond the bounds for that dimension, skip ahead to the next plausible key.

Joshua Bell
  • 7,727
  • 27
  • 30