Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there any way I can sort data based on time it's updated or created #867

Closed
ShivamJoker opened this issue Jul 1, 2019 · 5 comments
Closed

Comments

@ShivamJoker
Copy link

When I am creating the collection or updating the table of data is arranged based on the primary key value which i want it to be some id and i want to sort all the tables based on the time they are updated. Is there any built in method instead of storing the current update time and sorting it with sortBy

@dfahlander
Copy link
Collaborator

dfahlander commented Jul 2, 2019

You'd need to make sure to store the timestamp along with your other data and have that property indexed. Then you can utilize Table.orderBy() if you just want to list all entries by timestamp. If you need to combine it with a where clause but still have the result ordered by timestamp, there are three possible solutions:

  1. Create a compound index of for example name+timestamp. In your query, replace equals with between().
  2. Use orderBy('timestamp') combined with a filter.
  3. Use a where clause but sort the result using sortBy('timestamp')

Example code

const db = new Dexie('dbname');
db.version(1).stores({
  friends: '++id, timestamp, [name+timestamp]'
});
db.friends.bulkAdd([
  {name: "Foo", timestamp: Date.now()},
  {name: "Foo", timestamp: Date.now() + 1}, // adding 1 to emulate real world scenario
  {name: "Bar", timestamp: Date.now() + 2} // adding 2 to - " -
]).then(async ()=>{
  // order by timestamp:
  const friendsByTimeStamp = await db.friends
    .orderBy('timestamp').toArray();

  // Equality filter + order (similar to SQL "where name='Foo' order by timestamp")
  const foosByTimeStamp = await db.friends
    .where('[name+timestamp]').between(["Foo", Dexie.minKey], ["Foo", Dexie.maxKey])
    //.reverse() // unmark if reverse order is needed
    //.limit(x) // unmark if you want a limited set of results
    .toArray();

  // Utilize index for sorting. Filter manually. Can be the best when a limit is used.
  const friendsStartingWithF = await db.friends
    .orderBy('timestamp')
    //.reverse()
    .filter(x => x.name && x.name.toLowerCase().startsWith('f'))
    .limit(3)

  // Utilize index for query and sort the result in memory. Best when you need other than just equals() query and you don't use offset or limit.
  const friendsStartingWithF = await db.friends
    .where('name').startsWithIgnoreCase('f')
    .sortBy('timestamp');
}).catch(alert);

@ShivamJoker
Copy link
Author

Hey thanks for the example code i was also thinking about the same approach

@webdev23
Copy link

To catch all last entries, starting from a Unix date, and without further testings, I believe it's faster to, first avoid duplicate timestamp entries (with &timestamp), like so:

db.version(1).stores({ friends: '++id, &timestamp, [name+timestamp]' });

So we can do directly:

db.friends .where('[name+timestamp]').between(["FOO", 1647226800000], ["FOO", Dexie.maxKey]) .toArray()

Where the date 1647226800000 (~14 mars 2022) is an existing epoch timestamp in the db. (We have to make sure this entry does exists in the db).

It avoid iterating the whole db, to behave like a time-serie database.

@ZeeshanAhmadKhalil
Copy link

Is there a way to tell Dexie store timestamp itself (current time) when a new entry is added?

@dfahlander
Copy link
Collaborator

Is there a way to tell Dexie store timestamp itself (current time) when a new entry is added?

It's doable via Dexie.use

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants