Update all documents matching a list entry and create new documents for list entries without matches

Viewed 47

The problem

I have a MongoDB collection of Session documents with three fields: a user, a fromTimestamp and a toTimestamp. In my code, I have a list of users whose toTimestamps I need to update to now.

For every user on my list:

  • If there is an existing Session with the toTimestamp being no further than 1 minute ago, I want it updated to now.
  • If there isn't one, I want to create a new Session, with both fromTimestamps and toTimestamp being set to now.

Can I achieve this with one or two queries, in an efficient way?

Current solution

What I am currently doing, is using findMany to find all matching existing Sessions, getting their ID's and users. Then a bulk write with updateMany updates all the sessions with the collected ID's. A list of users gets created that were not returned from the initial query - these are the users that didn't have matching Sessions. For these, another bulk write inserts new Sessions.

However, this is 3 queries, and requires looping through all users to find which ones didn't have a matching Session. There might be thousands of users and I'm looking for a solution that will solve this efficiently, hopefully with a single query, without needing to compute differences in local code.

Sample data

Suppose the database contains these values:

Session(user: Alice, fromTimestamp: 0, toTimestamp: 10)

Session(user: Bob, fromTimestamp: 5, toTimestamp: 15)

Session(user: Claire: fromTimestamp: 0, toTimestamp: 20)

The timestamp now is 25. We get an update list of: Alice, Claire, Dan. Looking for sessions up to 10 ago, concerning these users, we find just Claire. Dan doesn't have a session already, Alice does, but it's toTimestamp is more than 10 ago. So there is only one session to update: Claire. It's toTimestamp is set to now, which is 25. That leaves Alice and Dan, for which we create new sessions. The resulting database is:

Session(user: Alice, fromTimestamp: 0, toTimestamp: 10)

Session(user: Bob, fromTimestamp: 5, toTimestamp: 15)

Session(user: Claire: fromTimestamp: 0, toTimestamp: 25)

Session(user: Alice: fromTimestamp: 25, toTimestamp: 25)

Session(user: Dan: fromTimestamp: 25, toTimestamp: 25)

For users with recent sessions, the sessions are extended. For users with no recent sessions, new sessions are created.

0 Answers
Related