Exploring Nested Data in MongoDB Aggregation using $match and $project

Struggling with crafting a Mongoose Aggregate Query to extract the permissions object of a specific member within a deeply nested structure of business data. MongoDB's documentation on this topic is lacking, making it hard for me to progress.

Sample Collection:

const business = [
    {
      b_id: ObjectId("a"),
      locations: [ 
        {
           l_id: ObjectId("b"),
           teams: [ 
               {
                  t_id: ObjectId("c"),
                  members: [ 
                        {
                            m_id: ObjectId("d"),
                            permissions: { 
                              p1: {
                                a: true,
                                b: false,
                                c: true,
                                d: false,
                              },
                              p2: {
                                a: true,
                                b: false,
                                c: true,
                                d: false,
                              }
                            }
                        }
                  ]
               } 
            ]
        }
      ]
    },
  ]

Expected outcome:

const permissions = {
  p1: {
    a: true,
    b: false,
    c: true,
    d: false,
  },
  p2: {
    a: true,
    b: false,
    c: true,
    d: false,
  }
}

Path:

router.post("/", authUser, (req, res) => {
  const _ids = {
    b_id: req.body.b_id,
    l_id: req.body.l_id,
    t_id: req.body.t_id,
    m_id: req.body.m_id,
  }
  Business.aggregate([
    {
      $match: {
        b_id: ObjectId(_ids.b_id),
      },
    },
    {
      $project: {
      //stuck on projecting the permissions object for the specified member
      },
    },
  ]).then((perms) => {
    console.log(perms);
  });
});

Any guidance would be greatly valued, thank you!

Answer №1

After some trial and error, I managed to come up with a solution that may not be the most elegant, but it does get the job done. Is there perhaps a more efficient way to approach this problem?

router.post("/", authUser, (req, res) => {
  const _ids = {
    b_id: req.body.b_id, //business _id === "a"
    l_id: req.body.l_id, //locations _id === "b"
    t_id: req.body.t_id, //teams _id === "c"
    m_id: req.body.m_id, //members _id === "d"
  }
  Business.aggregate([
    {
      $match: {
        b_id: ObjectId(_ids.b_id),
      },
    },
    {
      $unwind: "$locations",
    },
    {
      $match: {
        "locations.l_id": ObjectId(_ids.l_id),
      },
    },
    {
      $unwind: "$locations.teams",
    },
    {
      $match: {
        "locations.teams.t_id": ObjectId(_ids.t_id),
      },
    },
    {
      $unwind: "$locations.teams.members",
    },
    {
      $match: {
        "locations.teams.members.m_id": ObjectId(_ids.m_id),
      },
    },
    {
      $project: {
        permissions: ["$locations.teams.members.permissions"],
      },
    },
  ]).then((perms) => {
    res.status(200).send(perms[0].permissions[0]);
  });
});

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

Associating the object key and value with distinct attributes within the component

person = {name: 'Alice', age: '19', weight: 52} I'm looking to display both the keys and values from the object in one label and input field respectively. I attempted using Object.entries, but couldn't figure out how to sepa ...

Utilizing Font Awesome for social icons in a Vue component display

Currently, I'm in the process of building my own website and making the switch from traditional HTML, CSS, and JS to using VueJs. I've hit a roadblock when trying to transfer some code from my original HTML file to a Vue JS component, specificall ...

Removing the Login button from the layout page after the user has logged in can be achieved by

I am currently developing an MVC application in Visual Studio 2012. Within my layout page, there is a login button that I would like to hide after the user successfully logs in. Despite my attempts, the method I am using doesn't seem to be working. Ca ...

Bootstrap icon issue: square displaying instead of the intended icon

I am currently in the process of creating a responsive website using Bootstrap 3. I have successfully downloaded and imported Bootstrap 3 into the root directory of my website. However, I have encountered an issue where the icon does not display correctly ...

An unexpected error occurred during page generation. Any relevant console logs will be shown in the browser's terminal window

Encountered a RangeError: Maximum call stack size exceeded while compiling this web app in the browser. The error occurred on my header tag and sometimes on the return tag. What should I do? export default function Header() { return ( <> ...

Is there a proper method in AngularJS for factories to return objects?

I am facing an issue in retrieving POST data in an Angular.js project. This is the factory I am using: angular.module('mtApp').factory('getKey', function($http) { return { getData: function(data) { var key=&apos ...

Ways to handle <select> change events effectively in materialize css

My attempt at using a basic jquery change listener on a materialize css select dropdown has been unsuccessful. $("#somedropdown").change(function() { alert("Element Changed"); }); 1) Can anyone provide guidance on how to add a listener to ...

The previous and next arrows do not have a looping feature

I have a collection of 10 HTML pages stored in a folder called PROJECTS. Everything is functioning properly, except for the prev and next arrow navigation buttons. The issue arises when navigating to the last page (e.g., projectPage_10.html) from my Projec ...

Strangely odd actions from a JavaScript timepiece

After answering a question, I encountered a problem with my JavaScript clock that displays the day, time, and date on three lines. To make sure these lines have the same width, I used the BigText plugin, which works well except for one issue. tday=new A ...

Flag is activated to retrieve the data from the @Input source

@Input() config= []; flag = false; I need to change the flag to true only when I receive data in the config from the @input. Where should I do this? The data in the config is delayed and I am unable to access it in ngOnInit but can get it in ngOnChanges. ...

The selected value is not displayed in the Material UI select component

My select component is showing the menu items and allowing me to select them, but it's not displaying the selected value. However, its handle function is functioning correctly because when I choose an item, the value in the database gets updated. Bel ...

Ways to keep backend and frontend separate within Docker using Nuxt

I'm planning to divide my Nuxt app and dockerize the backend and frontend paths in separate folders. The structure of the project will have: my_nuxt_app |-backend |-frontend docker-compose.yaml Locally, this setup works fine with the foll ...

Having difficulty accessing a function within the SignalR connection function

I am currently facing an issue while trying to access a specific function within a SignalR connection function. Below is the code snippet showcasing the entire script for better understanding: $(function() { var chat = $.connection.chatHub; chat.c ...

Is there a way to search through an array of object arrays in JavaScript for a specific key/value pair using lodash or any other function?

I am faced with a task involving an array of objects. Each object has a key that needs to be used to search through sets of arrays containing similar objects. The goal is to determine if all the arrays contain the same value for a specific key in my object ...

What is the best way to modify an array's property in order to achieve the desired outcome when using json_encode?

Expected Result ['#ff0000','#4caf50','#4caf50','#4caf50','#00bcd4','#00bcd4','#4caf50','#4caf50'] The output I am receiving is as follows: ["'#ff0000','#4caf5 ...

Issue with JQuery time picker functionality not functioning properly upon repeat usage

I am facing an issue with a modal dialog that contains a form loaded via ajax. The form includes a time field populated using the jquery timepicker. Everything works perfectly when I open the dialog for the first time. However, if I try to load the dialog ...

Navigating within the constraints of a 16 million limit using a query that resembles a join

Considering the setup outlined below, is there a method by which I can search the people collection based on specific columns and receive an object structured like this? organization with people: { _id: "13efdsf31r23rwes" name: "Name", wp_slug ...

Controlling the visibility of components or elements in Angular through input modifications

Is there a more efficient way to handle button disabling and enabling based on email validation in Angular? I already have form controls set up, but want to make the process cleaner. The goal is to disable the "Get Started" button by default if the email a ...

Create a dynamic AppBar Toolbar in React Admin that changes based on the current page

Recently delving into the world of React, I've been facing some challenges when it comes to loading IconButtons onto the toolBar of an AppBar (from Material UI). For instance, I'm looking to have two specific IconButtons displayed on pageA and d ...

What separates the functions `useRef` and `createRef` from each other?

As I was delving into the hooks documentation, I came across useRef. Upon examining their example… function TextInputWithFocusButton() { const inputEl = useRef(null); const onButtonClick = () => { // `current` refers to the mounted text inpu ...