Querying subdocuments within an array using MongoDB's aggregation framework

Currently, I'm facing a challenge while developing a statistics dashboard for a meditation app. I'm struggling with creating a MongoDB query to fetch the most popular meditations based on user progress. The key collections involved are users and meditations.

The structure of a user document in the users collection is as follows:

{
   "_id":{
      "$oid":"627b519f73b2bd3375f5a7a5"
   },
   "userProgress":{
      "meditationsPracticed":[
         {
            "timestamp":"11.5.2022, 9:03:34",
            "id":"5ef2ff0af1a23752be00651f"
         },
         {
            "timestamp":"11.5.2022, 12:46:03",
            "id":"5eca520c10fe0480d350c9a4"
         },
         /* additional meditation entries */
      ]
   }
}

On the other hand, a meditation document in the meditations collection is structured like this:

{
   "_id":{
      "$oid":"5eca520c10fe0480d350c9ac"
   },
   "name":"Sleep Well",
   "duration":{
      "$numberInt":"250"
   }
}

My aim is to devise a query that retrieves the most popular meditations based on the id values stored in the meditationsPracticed array within the userProgress field of the user document.

Any assistance in crafting this MongoDB query would be highly appreciated. Thank you!

I've experimented with multiple queries utilizing $unwind and $lookup but haven't achieved success

Answer №1

Start by $unwinding at the meditationsPracticed level. Use $group to calculate the count based on the meditations id. Apply $rank along with $setWindowFields to handle scenarios with multiple top meditations counts. Next, use $lookup to retrieve the top meditation entry from the meditations collection.

db.users.aggregate([
  {
    "$match": {
      "_id": {
        "$oid": "627b519f73b2bd3375f5a7a5"
      }
    }
  },
  {
    "$unwind": "$userProgress.meditationsPracticed"
  },
  {
    "$group": {
      "_id": {
        "$toObjectId": "$userProgress.meditationsPracticed.id"
      },
      "count": {
        "$sum": 1
      }
    }
  },
  {
    "$setWindowFields": {
      "partitionBy": "$_id",
      "sortBy": {
        "count": -1
      },
      "output": {
        "rank": {
          "$rank": {}
        }
      }
    }
  },
  {
    "$match": {
      "rank": 1
    }
  },
  {
    "$lookup": {
      "from": "meditations",
      "localField": "_id",
      "foreignField": "_id",
      "as": "meditationsLookup"
    }
  },
  {
    "$unwind": {
      "path": "$meditationsLookup",
      "preserveNullAndEmptyArrays": true
    }
  }
])

Check out Mongo Playground for reference!

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

Utilizing a parent scope variable in a callback function

This question delves more into the concept of JavaScript Closures rather than Firebase. The issue arises in the code snippet below, where the Firebase callback fails to recognize the variable myArr from the outer scope. function show_fb() { var myAr ...

The Bootstrap navbar stubbornly refuses to hide after being clicked on

Is there a way to adjust the data-offset-top for mobile view? Additionally, I am having trouble hiding the menu when clicking on a link. I have tried some code from stackoverflow without success. Can someone please assist with this issue: <nav class= ...

"Optimizing navigation with dynamic link routing in AngularJS

I am working on a list of apartments displayed using ng-repeat. I need each apartment to be a clickable link that directs the user to view more details about that specific apartment. However, I am facing an issue where the links are not being repeated dyna ...

Troubleshooting Angular 2: Instances of Classes Not Being Updated When Retrieving Parameters

I am facing an issue with the following code snippet: testFunction() { let params = <any>{}; if (this.searchTerm) { params.search = this.searchTerm; } // change the URL this.router.navigate(['job-search'], {q ...

Two liquid level divs within a container with a set height

I hesitated to ask this question at first because it seemed trivial, but after spending over 3 hours searching on stackoverflow and Google, I decided to give it a shot. The issue I'm facing can be found here: http://jsfiddle.net/RVPkm/7/ In the init ...

Issues encountered when updating values in MaterialUI's TextField using Formik

Within my React functional component, I utilize Formik for form management and MaterialUI V5.10 for styling. The form includes TextField elements and a Canvas element. I am encountering two issues... Despite setting initial values in Formik, the TextFiel ...

Building TypeScript Model Classes

Greetings! As a newcomer to TypeScript with a background in both C# and JavaScript, I am on a quest to create class models resembling those found in C#. Here's my attempt so far: export class DonutChartModel { dimension: number; innerRadius: ...

Step-by-Step Guide for Uploading an Entire Folder and Its Contents

I have been working on a code to upload multiple files, but now I am facing the challenge of uploading an entire folder with multiple files and possibly subfolders containing even more files. Currently, I am utilizing JavaScript for obtaining the files and ...

Navigating through Next.js for slug URLs such as site.com/username

Can someone help me figure out how to create a profile page for each username, like site.com/jack or site.com/jill? I'll be pulling the username info from an API that also contains the user ID and email. I'm new to Next.js and would really appre ...

What could be causing TypeScript to throw errors regarding the initialState type when defining redux slices with createSlice in reduxToolkit, despite it being the correct type specified?

Here is my implementation of the createSlice() function: import { createSlice, PayloadAction } from "@reduxjs/toolkit"; type TransferDeckModeType = "pipetting" | "evaluation" | "editing"; var initialState: Transfer ...

Angular 14 Observables are not triggering resize events

There seems to be an issue here, as the code is not being triggered at all. The console log is not printing and this.width is not changing. constructor(private host: ElementRef, private zone: NgZone) {} public ngOnInit(): void { this.observer = new Re ...

How to use multiple template urls in Angular 6

Currently, I am creating a front-end using Angular 6 and facing the challenge of having components with varying html structures based on the user who is logged in. The number of templates required can range from 2 to over 20, so my preference would be to ...

Create a toggle effect using attribute selectors in CSS and JavaScript

I am looking to switch the "fill: #000;" from the CSS property "svg [id^='_']". Usually, I would use a method like this, but it seems that I can't do so because "svg [id^='_']" is not an element, correct? pub.toggleClass = functi ...

Manage image placement using CSS object-position

I have the following code snippet: img{ width: 100%; height: 1000px; object-fit: cover; object-position: left; } <!DOCTYPE html> <html lang="en"> <head> <meta charset ...

Exploring the power of Google Charts in conjunction with PHP arrays

I have three PHP arrays with key-value pairs: $needles = ["Needle1", "Needle2", "Needle3", "Needle4", "Needle5"]; $uph1 = ["Needle1" => 3, "Needle3" => 5, "Needle4" => 7]; $uph2 = ["Needle1" => 4, "Needle2" => 2, "Needle3" => 4]; ...

AngularJS: Identifying the position (ON/OFF) of ui-switch

I'm having trouble figuring out how to identify the position of my UI switch (true/false) in my JavaScript file. Here is my HTML file with the UI switch: <ui-switch ng-model='onOff'></ui-switch> And here is my controller for t ...

Express server controller encountering premature return from locally executed async function

I have developed an API endpoint using Node/Express. I am trying to call a local function asynchronously within the controller function, but instead of receiving the expected asynchronous results, the called local function is returning undefined immediat ...

Convert JavaScript objects to strings with JSON strings already included as values

Although this question may seem like a duplicate, I have not been able to find the answer. My issue is with stringifying a JavaScript object that contains JSON strings as values. Here is an example: var obj = {id:1, options:"{\"code\":3,\" ...

Using keyof to access static properties within TypeScript classes

While experimenting with this TypeScript playground code sample, I encountered an issue with defining the greeterBuilderName variable. How can I specify that I want properties of the Greeter function itself (such as prototype, warm_greeter, etc.) when keyo ...

Sending Paypal IPN Data to Node.JS: A Step-by-Step Guide

I'm looking to implement a real-time donation system on my website that can update all users simultaneously. The challenge I'm facing is that the IPN (Instant Payment Notification) page, responsible for verifying payments, is written in PHP. Unf ...