TinyBase logoTinyBase

setIndexDefinition

The setIndexDefinition method lets you set the definition of an Index.

setIndexDefinition(
  indexId: Id,
  tableId: Id,
  getSliceIdOrIds?: any,
  getSortKey?: any,
  sliceIdSorter?: (sliceId1: Id, sliceId2: Id) => number,
  rowIdSorter?: (sortKey1: SortKey, sortKey2: SortKey, sliceId: Id) => number,
): Indexes
TypeDescription
indexIdId

The Id of the Index to define.

tableIdId

The Id of the Table the Index will be generated from.

getSliceIdOrIds?any

Either the Id of the Cell containing, or a function that produces, the Id that is used to indicate which Slice in the Index the Row Id should be in. Defaults to a function that returns '' (meaning that if this getSliceIdOrIds parameter is omitted, the Index will simply contain a single Slice containing all the Row Ids in the Table). Since v2.1, this can return an array of Slice Ids, each of which the Row will then belong to.

getSortKey?any

Either the Id of the Cell containing, or a function that produces, the value that is used to sort the Row Ids in each Slice.

sliceIdSorter?(sliceId1: Id, sliceId2: Id) => number

A function that takes two Slice Id values and returns a positive or negative number to indicate how they should be sorted.

rowIdSorter?(sortKey1: SortKey, sortKey2: SortKey, sliceId: Id) => number

A function that takes two Row Id values (and a slice Id) and returns a positive or negative number to indicate how they should be sorted.

returnsIndexes

A reference to the Indexes object.

Every Index definition is identified by a unique Id, and if you re-use an existing Id with this method, the previous definition is overwritten.

An Index is a keyed map of Slice objects, each of which is a list of Row Ids from a given Table. Therefore the definition must specify the Table (by its Id) to be indexed.

The Ids in a Slice represent Row objects from a Table that all have a derived string value in common, as described by this method. Those values are used as the key for each Slice in the overall Index object.

Without the third getSliceIdOrIds parameter, the Index will simply have a single Slice, keyed by an empty string. But more often you will specify a Cell value containing the Slice Id that the Row should belong to. Alternatively, a custom function can be provided that produces your own Slice Id from the local Row as a whole. Since v2.1, the custom function can return an array of Slice Ids, each of which the Row will then belong to.

The fourth getSortKey parameter specifies a Cell Id to get a value (or a function that processes a whole Row to get a value) that is used to sort the Row Ids within each Slice in the Index.

The fifth parameter, sliceIdSorter, lets you specify a way to sort the Slice Ids when you access the Index, which may be useful if you are trying to create an alphabetic Index of Row entries. If not specified, the order of the Slice Ids will match the order of Row insertion.

The final parameter, rowIdSorter, lets you specify a way to sort the Row Ids within each Slice, based on the getSortKey parameter. This may be useful if you are trying to keep Rows in a determined order relative to each other in the Index. If omitted, the Row Ids are sorted alphabetically, based on the getSortKey parameter.

The two 'sorter' parameters, sliceIdSorter and rowIdSorter, are functions that take two values and return a positive or negative number for when they are in the wrong or right order, respectively. This is exactly the same as the 'compareFunction' that is used in the standard JavaScript array sort method, with the addition that rowIdSorter also takes the Slice Id parameter, in case you want to sort Row Ids differently in each Slice. You can use the convenient defaultSorter function to default this to be alphanumeric.

Examples

This example creates a Store, creates an Indexes object, and defines a simple Index based on the values in the species Cell.

const store = createStore().setTable('pets', {
  fido: {species: 'dog'},
  felix: {species: 'cat'},
  cujo: {species: 'dog'},
});

const indexes = createIndexes(store);
indexes.setIndexDefinition('bySpecies', 'pets', 'species');

console.log(indexes.getSliceIds('bySpecies'));
// -> ['dog', 'cat']
console.log(indexes.getSliceRowIds('bySpecies', 'dog'));
// -> ['fido', 'cujo']

This example creates a Store, creates an Indexes object, and defines an Index based on the first letter of the pets' names.

const store = createStore().setTable('pets', {
  fido: {species: 'dog'},
  felix: {species: 'cat'},
  cujo: {species: 'dog'},
});

const indexes = createIndexes(store);
indexes.setIndexDefinition('byFirst', 'pets', (_, rowId) => rowId[0]);

console.log(indexes.getSliceIds('byFirst'));
// -> ['f', 'c']
console.log(indexes.getSliceRowIds('byFirst', 'f'));
// -> ['fido', 'felix']

This example creates a Store, creates an Indexes object, and defines an Index based on each of the letters present in the pets' names.

const store = createStore().setTable('pets', {
  fido: {species: 'dog'},
  felix: {species: 'cat'},
  rex: {species: 'dog'},
});

const indexes = createIndexes(store);
indexes.setIndexDefinition('containsLetter', 'pets', (_, rowId) =>
  rowId.split(''),
);

console.log(indexes.getSliceIds('containsLetter'));
// -> ['f', 'i', 'd', 'o', 'e', 'l', 'x', 'r']
console.log(indexes.getSliceRowIds('containsLetter', 'i'));
// -> ['fido', 'felix']
console.log(indexes.getSliceRowIds('containsLetter', 'x'));
// -> ['felix', 'rex']

This example creates a Store, creates an Indexes object, and defines an Index based on the first letter of the pets' names. The Slice Ids (and Row Ids within them) are alphabetically sorted.

const store = createStore().setTable('pets', {
  fido: {species: 'dog'},
  felix: {species: 'cat'},
  cujo: {species: 'dog'},
});

const indexes = createIndexes(store);
indexes.setIndexDefinition(
  'byFirst', //              indexId
  'pets', //                 tableId
  (_, rowId) => rowId[0], // each Row's sliceId
  (_, rowId) => rowId, //    each Row's sort key
  defaultSorter, //          sort Slice Ids
  defaultSorter, //          sort Row Ids
);

console.log(indexes.getSliceIds('byFirst'));
// -> ['c', 'f']
console.log(indexes.getSliceRowIds('byFirst', 'f'));
// -> ['felix', 'fido']