Reputation: 4737
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
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:
Upvotes: 1
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.
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.
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
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
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