Tips for choosing the most recent entry for each category in a MongoDB database using typescript and mongoose

My mongoDB collection is structured like this:

[
 {user: "joe",  event: "foo", timestamp: 1},
 {user: "meg",  event: "blah", timestamp: 2},
 {user: "rick", event: "bork", timestamp: 3},
 {user: "joe",  event: "bing", timestamp: 4},
 {user: "meg",  event: "biz",  timestamp: 5},
 {user: "tim",  event: "boz",  timestamp: 6}
]

I am aiming to identify the most recent event for each user, resulting in a set of data as follows:

[
 {user: "rick", event: "bork", timestamp: 3},
 {user: "joe",  event: "bing", timestamp: 4},
 {user: "meg",  event: "biz",  timestamp: 5},
 {user: "tim",  event: "boz",  timestamp: 6}
]

Although I have reviewed the mongoose aggregation framework documentation, I haven't found a direct solution. Many examples group by user but lose some details in the process. I am unsure how to preserve the complete documents at the end.

Answer №1

  1. $setWindowFields - Group the data by the user field, order each group by timestamp in descending order, and assign a rank to each document using the $rank operator.

  2. $match - Filter the documents where rank: 1, selecting only the latest timestamp for each user.

  3. $sort - Sort the documents by timestamp in ascending order.

  4. $unset - Remove the rank field from the output.

db.collection.aggregate([
  {
    $setWindowFields: {
      partitionBy: "$user",
      sortBy: {
        timestamp: -1
      },
      output: {
        rank: {
          $rank: {}
        }
      }
    }
  },
  {
    $match: {
      rank: 1
    }
  },
  {
    $sort: {
      timestamp: 1
    }
  },
  {
    , $unset: "rank"
  }
])

Check out the demo on Mongo Playground

Answer №2

If you combine the sort, group, and project functions, I have a solution available

db.collection.aggregate([
  { $sort: { timestamp: -1 } },

  {
    $group: {
      _id: '$user',
      doc: { $first: '$$ROOT' },
    },
  },
  {
    $project: {
      _id: 0,
      user: '$doc.user',
      event: '$doc.event',
      timestamp: '$doc.timestamp',
    },
  },
])

This method allows you to retain all document information during the process

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it possible to adjust the position/target values of a webkit CSS transition without interrupting its operation

Is there a way to smoothly change the target position or attributes of a running transition without halting it? To illustrate, let's consider this initial animation: -webkit-transition:-webkit-transform 5s ease-in-out -webkit-transform: translate3d( ...

Display cautionary message upon the deletion of a row from a gridview in asp.net

I have implemented a gridview on my web form that includes a command field for delete and edit functionalities. My goal is to display a javascript alert message when a user clicks on the delete button: Are you sure you want to delete this record? If t ...

How can I resize several images to fit seamlessly within a div container?

Looking for a smart method to resize multiple images to fit neatly inside a fixed-size div? I've considered using JavaScript to calculate the div's width, dividing it by the number of images, and resizing them equally while maintaining their asp ...

The MongoDB .push operation is returning a null value

Take a look at the GitHub repository where I am actively working: https://github.com/Stick-z/first-media-app I'm currently in the process of creating a website and focusing on the backend development. One of my tasks involves setting up a jokes array ...

Encountering Unmet Dependency Issue When Running 'npm install' on Laravel in Windows 8

Currently, I am in the process of working on a Laravel project and looking to utilize Elixir to handle my front-end tasks. After running 'npm install', I encountered a warning stating "npm WARN unmet dependency". What steps should I take in order ...

Leveraging the power of mapState and mapMutations within a namespaced module

I'm having trouble accessing mutations and states after dividing my Vuex store into three modules. I've attempted various syntaxes, but none seem to be working for me. MapStates: This is how I have set up the mapStates, with 'vendor' a ...

Identify the specific button that triggers a JavaScript function

Currently, I am working on an admin page that displays a list of posts using EJS for template rendering engine. <table> <tr> <th>Name</th> <th>Description</th> </tr> <% projects.for ...

Is it possible to specify the input language for a textbox or textarea in a web form?

I am currently working on developing a website in Urdu language, with features similar to that of a blogging platform. To ensure that all posts are written only in Urdu, I am exploring different options. One idea I have is to use a Javascript code that ca ...

Creating image paths for a list of items in reactjs can be achieved by mapping through the list

My goal is to display a list of items, with each item being assigned an image based on its ID: private static renderItemsTable(products: Product[]) { return <table className='table'> <thead> <tr> ...

What is the best way to create a reset button for a timing device?

Is there a way to reset the timer when a button is clicked? Having a reset button would allow users to revisit the timer multiple times without it displaying the combined time from previous uses. Check out this code snippet for one of the timers along wit ...

Using Ionic2, include NavController into Injectable Service

Having an issue with an Injectable Service in Angular2 with Ionic2 framework. Here is how my service is structured: import {Injectable} from '@angular/core'; import {NavController} from 'ionic-angular'; @Injectable() export class Vie ...

What is the best method for toggling between three different elements in an array?

I have been working on a language switcher feature in my Next.js project. The idea is to have three languages available, with the ability for the user to click on a language and have it become the active one, while moving the previously active language t ...

Obtaining PHP array via asynchronous JavaScript and XML (AJ

Having never done it before, I am trying to implement comments using AJAX. Despite hours of searching on Google, I find myself stuck and unsure if I am going about it the right way. My goal is to enable users to add a comment without having to reload the ...

Exploring the capabilities of Open Layers through selenium

We are facing a challenge with automating clicks on map elements that are svg nodes, as they do not have specific x-paths that selenium relies on. Even attempting to click on features has also proven unsuccessful since they are set as svg elements. Is th ...

Limiting the movement of the mouse within a specific div using the jQuery library

Is there a way to limit mouse movement within a specific div area when the right button is clicked using the jQuery library? Alternatively, could someone provide guidance on how to achieve this, similar to restricting the movement of a portion of the scr ...

Developing a Generic API Invocation Function

I'm currently working on a function that has the capability to call multiple APIs while providing strong typing for each parameter: api - which represents the name of the API, route - the specific route within the 'api', and params - a JSON ...

How is it that when a function is called with just one parameter, it ends up receiving the entire element?

In my table, I have various item numbers listed with corresponding quantity input fields identified by id="itemNumber". Each line also includes a button that triggers a function (onclick="addItemAndQuantity(itemNumber)") to retrieve inf ...

Tips for referencing Google Maps initialization in individual files within a website application

After setting up my Google Maps API snippet: <script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap"></script> in the index.html file, I encountered the error: Uncaught InvalidValueEr ...

The hamburger menu functions properly on the homepage but is not working on the individual about page

The burger menu was causing issues initially due to a simple spelling mistake, which I only noticed later. However, the current issue seems more complex. I am now creating separate pages for different sections of my website, such as About Me, Education, et ...

SweetAlert html is not recognizing ng-app, but it functions correctly within the html body

When inserting a bootstrap table inside a SweetAlert, I encountered an issue where using ng-app or ng-repeat to populate data inside the table's rows did not call ng-app. However, when populating the table outside of the SweetAlert in the body, ng-app ...