0

Consider, I have an IndexedDB database with a composite key, e.g.: [prop1, prop2].

Is it possible to do a partial query where only one part of the key is known to return multiple records from the database?

This will be equivalent to the following SQL query:

SELECT * FROM table WHERE prop1 = 'foo'

OR:

SELECT * FROM table WHERE prop2 = 'bar'

I've tried to use getAll() method, but it looks like it's expecting value for both parts of the key.

If it's not possible — what alternative could be considered instead?

Josh
  • 17,834
  • 7
  • 50
  • 68
Slava Fomin II
  • 26,865
  • 29
  • 124
  • 202

2 Answers2

1

I'm still not sure if partial query is actually possible for the composite key, however, I've decided to switch to a different strategy:

The idea is to use auto-generated primary key for the store and then to create two separate indices for the prop1 and prop2. This way, you can query both properties separately. This suits my use-case pretty well:

// Example uses "idb" package from npm

const store = database.createObjectStore('resources', {
  keyPath: 'id',
  autoIncrement: true,
});

store.createIndex('url', 'url');

store.createIndex('hash', 'hash');

However, I think that you can use two additional indices with the composite primary key as well if you need some uniqueness guarantees. Probably this would be less effective, than using the index of the primary key directly.

Slava Fomin II
  • 26,865
  • 29
  • 124
  • 202
  • 2
    This is probably the best approach. You can't simply do a query on part of a composite key. The closest you can get is iterating a cursor and advancing. Similar examples in https://stackoverflow.com/questions/16522115/indexed-db-cursor-ranges-on-multiple-properties/32976384#32976384 – Joshua Bell May 27 '21 at 16:11
  • That's not entirely true. You can query a composite key on an index with `IDBKeyRange.bound([x], [x, []])` (notice the empty array). https://stackoverflow.com/a/46098585/480608 – Raine Revere Jun 09 '23 at 15:32
0

Yes you can do a partial query because you can compare arrays of different lengths. But the results will not be great. You can basically re-use the first element of the composite array as its own index. But, also, results with undefined on the second element might not be there.

You can do this trivially for prop1 by using a query value like [prop1value]. You cannot, however, do this trivially for prop2.

Josh
  • 17,834
  • 7
  • 50
  • 68