g00fy
g00fy

Reputation: 4737

IndexedDB - boolean index

Is it possible to create an index on a Boolean type field?

Lets say the schema of the records I want to store is:

{
  id:1,
  name:"Kris",
  _dirty:true
}

I created normal not unique index (onupgradeneeded):

...
store.createIndex("dirty","_dirty",{ unique: false })
...

The index is created, but it is empty! - In the index IndexedDB browser there are no records with Boolean values - only Strings, Numbers and Dates or even Arrays.

I am using Chrome 25 canary

I would like to find all records that have _dirty attribute set to true - do I have to modify _dirty to string or int then?

Upvotes: 20

Views: 4774

Answers (5)

David
David

Reputation: 525

Another alternative is to split the data into two separate object stores as commands_synced_to_server and commands_not_synced_to_server.

Then reading all commands_not_synced_to_server is the fastest as there is no lookup required from an index to the data and you are only reading the needed items.

The disadvantages are:

  • It adds complexity.
  • If you update the boolean field you need to delete the item from the true_values object store and insert it into the false_values object store.
  • If you query and you do not know the boolean value, then you need to query two object stores. Since the query runs async, I would assume that there is not much performance difference compared to a single store. You could also duplicate all data to a third object store to optimize this case.

Upvotes: 1

user10294571
user10294571

Reputation:

I've used 0 and 1 instead of boolean type.

Upvotes: 1

Josh
Josh

Reputation: 18690

The answer marked as checked is not entirely correct.

You cannot create an index on a property that contains values of the Boolean JavaScript type. That part of the other answer is correct. If you have an object like var obj = {isActive: true};, trying to create an index on obj.isActive will not work and the browser will report an error message.

However, you can easily simulate the desired result. indexedDB does not insert properties that are not present in an object into an index. Therefore, you can define a property to represent true, and not define the property to represent false. When the property exists, the object will appear in the index. When the property does not exist, the object will not appear in the index.

Example

For example, suppose you have an object store of 'obj' objects. Suppose you want to create a boolean-like index on the isActive property of these objects.

Start by creating an index on the isActive property. In the onupgradeneeded callback function, use store.createIndex('isActive','isActive');

To represent 'true' for an object, simply use obj.isActive = 1;. Then add or put the object into the object store. When you want to query for all objects where isActive is set, you simply use db.transaction('store').index('isActive').openCursor();.

To represent false, simply use delete obj.isActive; and then add or or put the object into the object store.

When you query for all objects where isActive is set, these objects that are missing the isActive property (because it was deleted or never set) will not appear when iterating with the cursor.

Voila, a boolean index.

Performance notes

Opening a cursor on an index like was done in the example used here will provide good performance. The difference in performance is not noticeable with small data, but it is extremely noticeable when storing a larger amount of objects. There is no need to adopt some third party library to accomplish 'boolean indices'. This is a mundane and simple feature you can do on your own. You should try to use the native functionality as much as possible.

Upvotes: 11

Konstantin Isaev
Konstantin Isaev

Reputation: 662

Boolean properties describe the exclusive state (Active/Inactive), 'On/Off', 'Enabled/Disabled', 'Yes/No'. You can use these value pairs instead of Boolean in JS data model for readability. Also this tactic allow to add other states ('NotSet', for situation if something was not configured in object, etc.)...

Upvotes: 0

Kyaw Tun
Kyaw Tun

Reputation: 13131

Yes, boolean is not a valid key.

If you must, of course you can resolve to 1 and 0.

But it is for good reason. Indexing boolean value is not informative. In your above case, you can do table scan and filter on-the-fly, rather than index query.

Upvotes: 9

Related Questions