Version.stores()
Syntax
version.stores(schemaDefinition);
Parameters
schemaDefinition : Object | Object where each key represents the name of an object store and each value represents the primary and secondary indexes |
Return Value
Description
Specifies tables to be added, altered or deleted in this version. Each key in the schemaDefinition argument represents a table name and each value represents the primary key followed by the list of indexed properties. NOTE: Unlike SQL, you donât need to specify all properties but only the one you wish to index.
WARNING
Never index properties containing images, movies or large (huge) strings. Store them in IndexedDB, yes! but just donât index them!
db.version(1).stores({
friends: '++id, name, age' // don't index "picture"
});
db.friends.put({
name: 'Camilla',
age: 25,
picture: await getBlob('camilla.png') // but store it
});
Example how the âpictureâ property is stored without being indexed.
Writing this because there have been some issues on github where people index images or movies without really understanding the purpose of indexing fields. A rule of thumb: Are you going to put your property in a where(ââŠâ) clause? If yes, index it, if not, dont. Large indexes will affect database performance and in extreme cases make it unstable.
Changing the Schema
Please refer to Database Versioning that explains how to add, alter or remove a table using the Versioning framework in Dexie.
Schema Syntax
++ | Auto-incremented primary key |
& | Unique index |
* | Multi-entry index |
[A+B] | Compound index or primary key |
Detail: Primary keys are implicitly marked as unique.
Indexable Types
Only properties of certain types can be indexed. This includes string, number, Date and Array but NOT boolean, null or undefined. Indexing a property path that turns out to hold a non-indexable type will have no effect. And using orderBy() with that property will NOT list that object.
Detailed Schema Syntax
The first entry in the schema string will always represent the primary key.
Syntax For Primary Key | ||
++keyPath | Autoincrement primary key | Means that the primary key will be auto-incremented. Primary key must always be unique. |
++ | Hidden autoincremented primary key | Means that primary key is auto-incremented but not visible on the objects. |
keyPath | Don't autoincrement primary key | Means that primary key can be any type and we have to provide it ourself |
(blank) | Hidden primary key | Leaving the first entry blank means that primary key is hidden and not auto-incremented |
Syntax For Indexes | ||
keyPath | Means that keyPath is indexed | |
&keyPath | Unique | Means that keyPath is indexed and keys must be unique |
*keyPath | Multi-valued | Means that if key is an array, each array value will be regarded as a key to the object. |
[keyPath1+keyPath2] | Compound | Defining a compound index for keyPath1 and keyPath2 |
NOTE: keyPath represents a property name or a dotted path to a nested property.
Sample
var db = new Dexie('MyDatabase');
db.version(1).stores({
friends: '++id,name,shoeSize', // Primary Key is auto-incremented (++id)
pets: 'id, name, kind', // Primary Key is not auto-incremented (id)
cars: '++, name', // Primary Key auto-incremented but not inbound
enemies: ',name,*weaknesses', // Primary key is neither inbound nor auto-incr
// 'weaknesses' contains an array of keys (*)
users: 'meta.ssn, addr.city', // Dotted keypath refers to nested property
people: '[name+ssn], &ssn' // Compound primary key. Unique index ssn
});
Detailed Sample
This sample shows how to define the schema of a given version:
var db = new Dexie("FriendsAndPetsDatabase");
db.version(1).stores({
users: "++id, name, &username, *email, address.city",
relations: "++, userId1, userId2, [userId1+userId2], relation"
});
db.open().catch(function (e) {
console.error("Open failed: " + e.stack);
})
db.transaction('rw', db.users, function () {
db.users.add({
name: "Zlatan",
username: "ibra",
email: [
"zlatan@ibrahimovic.se",
"zlatan.ibrahimovic@gmail.com"
],
address: {
city: "Malmö",
country: "Sweden"
}
});
db.users.where("email").startsWith("zlatan")
.or("address.city").anyOf (["Malmö", "Stockholm", "Barcelona"])
.each(function (user) {
console.log("Found user: " + user.name);
});
}).catch (function (e) {
console.error(e.stack);
});
Detailed Sample Explained
- Table âusersâ has:
- an auto-incremented primary key named id.
- an index on the name property which could be of any type.
- a unique index on the username property.
- a multi index on the email property, meaning that it allow multiple emails and the possibility to index each of them and find the single user object. NOTE! This feature lacks support in IE.
- an index on the nested property âaddress.cityâ.
- Table ârelationsâ doesnât have a âvisibleâ primary key (however, it must have one autoincremented internally).
- Table ârelationsâ has index on the userId1, userId2 and relation properties.
- Table ârelationsâ has a compound index of the properties userId1 and userId2 combined NOTE! This feature lacks support in IE.
Queries you could do with these indexes:
db.users.get(2)
will give you the user with id 2db.users.where('name').startsWithIgnoreCase('da')
- will give you all users starting with âdaâdb.users.where('username').equals('usrname').first()
- will give you the user with username âusrnameâdb.users.where('email').startsWith('david@').distinct()
- will give you the users that have any of their emails starting with âdavid@âdb.users.where('address.city').equalsIgnoreCase('malmö')
- will give you all users residing in Malmö.db.relations.where('userId1').equals(2)
- will give you all relations that user with id 2 has to other usersdb.relations.where('relation').anyOf('wife', 'husband', 'son', 'daughter')
- will give you all family relations.db.relations.where('userId1').equals(2).or('userId2').equals(2)
- will give you all relations that user with id 2 has to other users or other users have to user 2db.relations.where('[userId1+userId2]').equals([2,3])
- will give you all the relations that user 2 has to user 3db.relations.where('[userId1+userId2]').equals([2,3]).or('[userId1+userId2]').equals([3,2])
- will give you all the relations that user 2 has to user 3 or user 3 has to user 2.
Table of Contents
- API Reference
- Access Control in Dexie Cloud
- Add demo users
- Add public data
- Authentication in Dexie Cloud
- Best Practices
- Building Addons
- Collection
- Collection.and()
- Collection.clone()
- Collection.count()
- Collection.delete()
- Collection.desc()
- Collection.distinct()
- Collection.each()
- Collection.eachKey()
- Collection.eachPrimaryKey()
- Collection.eachUniqueKey()
- Collection.filter()
- Collection.first()
- Collection.keys()
- Collection.last()
- Collection.limit()
- Collection.modify()
- Collection.offset()
- Collection.or()
- Collection.primaryKeys()
- Collection.raw()
- Collection.reverse()
- Collection.sortBy()
- Collection.toArray()
- Collection.uniqueKeys()
- Collection.until()
- Compound Index
- Consistency in Dexie Cloud
- Consistent add() operator
- Consistent remove() operator
- Consistent replacePrefix() operator
- Consuming Dexie as a module
- Custom Emails in Dexie Cloud
- DBCore
- DBCoreAddRequest
- DBCoreCountRequest
- DBCoreCursor
- DBCoreDeleteRangeRequest
- DBCoreDeleteRequest
- DBCoreGetManyRequest
- DBCoreGetRequest
- DBCoreIndex
- DBCoreKeyRange
- DBCoreMutateRequest
- DBCoreMutateResponse
- DBCoreOpenCursorRequest
- DBCorePutRequest
- DBCoreQuery
- DBCoreQueryRequest
- DBCoreQueryResponse
- DBCoreRangeType
- DBCoreSchema
- DBCoreTable
- DBCoreTableSchema
- DBCoreTransaction
- DBCoreTransactionMode
- DBPermissionSet
- Deprecations
- Derived Work
- Design
- Dexie Cloud API
- Dexie Cloud API Limits
- Dexie Cloud Best Practices
- Dexie Cloud CLI
- Dexie Cloud Docs
- Dexie Cloud REST API
- Dexie Cloud Web Hooks
- Dexie Constructor
- Dexie.AbortError
- Dexie.BulkError
- Dexie.ConstraintError
- Dexie.DataCloneError
- Dexie.DataError
- Dexie.DatabaseClosedError
- Dexie.IncompatiblePromiseError
- Dexie.InternalError
- Dexie.InvalidAccessError
- Dexie.InvalidArgumentError
- Dexie.InvalidStateError
- Dexie.InvalidTableError
- Dexie.MissingAPIError
- Dexie.ModifyError
- Dexie.NoSuchDatabaseErrorError
- Dexie.NotFoundError
- Dexie.Observable
- Dexie.Observable.DatabaseChange
- Dexie.OpenFailedError
- Dexie.PrematureCommitError
- Dexie.QuotaExceededError
- Dexie.ReadOnlyError
- Dexie.SchemaError
- Dexie.SubTransactionError
- Dexie.Syncable
- Dexie.Syncable.IDatabaseChange
- Dexie.Syncable.IPersistentContext
- Dexie.Syncable.ISyncProtocol
- Dexie.Syncable.StatusTexts
- Dexie.Syncable.Statuses
- Dexie.Syncable.registerSyncProtocol()
- Dexie.TimeoutError
- Dexie.TransactionInactiveError
- Dexie.UnknownError
- Dexie.UnsupportedError
- Dexie.UpgradeError()
- Dexie.VersionChangeError
- Dexie.VersionError
- Dexie.[table]
- Dexie.addons
- Dexie.async()
- Dexie.backendDB()
- Dexie.close()
- Dexie.currentTransaction
- Dexie.debug
- Dexie.deepClone()
- Dexie.defineClass()
- Dexie.delByKeyPath()
- Dexie.delete()
- Dexie.derive()
- Dexie.events()
- Dexie.exists()
- Dexie.extend()
- Dexie.fakeAutoComplete()
- Dexie.getByKeyPath()
- Dexie.getDatabaseNames()
- Dexie.hasFailed()
- Dexie.ignoreTransaction()
- Dexie.isOpen()
- Dexie.js
- Dexie.name
- Dexie.on()
- Dexie.on.blocked
- Dexie.on.close
- Dexie.on.error
- Dexie.on.populate
- Dexie.on.populate-(old-version)
- Dexie.on.ready
- Dexie.on.storagemutated
- Dexie.on.versionchange
- Dexie.open()
- Dexie.override()
- Dexie.semVer
- Dexie.setByKeyPath()
- Dexie.shallowClone()
- Dexie.spawn()
- Dexie.table()
- Dexie.tables
- Dexie.transaction()
- Dexie.transaction()-(old-version)
- Dexie.use()
- Dexie.verno
- Dexie.version
- Dexie.version()
- Dexie.vip()
- Dexie.waitFor()
- DexieCloudOptions
- DexieError
- Docs Home
- Download
- EntityTable
- Export and Import Database
- Get started with Dexie in Angular
- Get started with Dexie in React
- Get started with Dexie in Svelte
- Get started with Dexie in Vue
- Hello World
- How To Use the StorageManager API
- Inbound
- IndexSpec
- Indexable Type
- IndexedDB on Safari
- Invite
- Member
- Migrating existing DB to Dexie
- MultiEntry Index
- PersistedSyncState
- Privacy Policy
- Promise
- Promise.PSD
- Promise.catch()
- Promise.finally()
- Promise.on.error
- Promise.onuncatched
- Questions and Answers
- Realm
- Releasing Dexie
- Road Map
- Road Map: Dexie 5.0
- Road Map: Dexie Cloud
- Role
- Run Dexie Cloud on Own Servers
- Sharding and Scalability
- Simplify with yield
- Support Ukraine
- SyncState
- Table
- Table Schema
- Table.add()
- Table.bulkAdd()
- Table.bulkDelete()
- Table.bulkGet()
- Table.bulkPut()
- Table.bulkUpdate()
- Table.clear()
- Table.count()
- Table.defineClass()
- Table.delete()
- Table.each()
- Table.filter()
- Table.get()
- Table.hook('creating')
- Table.hook('deleting')
- Table.hook('reading')
- Table.hook('updating')
- Table.limit()
- Table.mapToClass()
- Table.name
- Table.offset()
- Table.orderBy()
- Table.put()
- Table.reverse()
- Table.schema
- Table.toArray()
- Table.toCollection()
- Table.update()
- Table.where()
- The main limitations of IndexedDB
- Transaction
- Transaction.abort()
- Transaction.on.abort
- Transaction.on.complete
- Transaction.on.error
- Transaction.table()
- Tutorial
- Typescript
- Typescript (old)
- Understanding the basics
- UserLogin
- Version
- Version.stores()
- Version.upgrade()
- WhereClause
- WhereClause.above()
- WhereClause.aboveOrEqual()
- WhereClause.anyOf()
- WhereClause.anyOfIgnoreCase()
- WhereClause.below()
- WhereClause.belowOrEqual()
- WhereClause.between()
- WhereClause.equals()
- WhereClause.equalsIgnoreCase()
- WhereClause.inAnyRange()
- WhereClause.noneOf()
- WhereClause.notEqual()
- WhereClause.startsWith()
- WhereClause.startsWithAnyOf()
- WhereClause.startsWithAnyOfIgnoreCase()
- WhereClause.startsWithIgnoreCase()
- db.cloud.configure()
- db.cloud.currentUser
- db.cloud.currentUserId
- db.cloud.events.syncComplete
- db.cloud.invites
- db.cloud.login()
- db.cloud.logout()
- db.cloud.options
- db.cloud.permissions()
- db.cloud.persistedSyncState
- db.cloud.roles
- db.cloud.schema
- db.cloud.sync()
- db.cloud.syncState
- db.cloud.userInteraction
- db.cloud.usingServiceWorker
- db.cloud.version
- db.cloud.webSocketStatus
- db.members
- db.realms
- db.roles
- db.syncable.connect()
- db.syncable.delete()
- db.syncable.disconnect()
- db.syncable.getOptions()
- db.syncable.getStatus()
- db.syncable.list()
- db.syncable.on('statusChanged')
- db.syncable.setFilter()
- dexie-cloud-addon
- dexie-react-hooks
- liveQuery()
- unhandledrejection-event
- useLiveQuery()
- useObservable()
- usePermissions()