Excluding null values when using Mongoose populate query: A simple guide

I'm currently working on an app where I've defined 2 models.

  const UserSchema = new Schema({
    _id: Schema.Types.ObjectId,
    account:{
      type: String,
      unique: true
    }, 
    email: String,
    first_name: String,
    last_name: String
}

  const VenueSchema = new Schema({
    _id: Schema.Types.ObjectId,
    venue_type: String,
    capacity: Number
  })

and

const MediatorSchema = new Schema({
    _id: Schema.Types.ObjectId,
    account:{
      type: String,
      unique: true
    },
    user: {type: Schema.Types.ObjectId, 
      ref:'User'
    }
    venue: {type: Schema.Types.ObjectId, 
      ref:'Venue'
    }
  })

The purpose of the mediator schema is to link multiple paths together.

The issue arises when attempting to perform a query like:

var populateQuery = [{path:'user',match: { account:'testuser1'},select:'email'},{path:'venue',match: { venue_type: 'club'}, select:'venue_type'}];

const confirmedVenues = await  Mediator.find({})  
.exists('venue',true)
.populate(populateQuery)
.exec();

The resulting array contains objects with null values if the specified match criteria are not met.

For instance, with the provided matches, the results look like this:

https://i.sstatic.net/Jz3sR.png

What I am aiming for is that if a user or venue (or any other criteria) is NULL, the entire object should not be returned.

I did come up with a solution, but I'm looking for a better approach:

var i =confirmedVenues.length;
while(i--){
  if(confirmedVenues[i].user == null){
    temp.splice(i,1)
  }
}

Answer №1

After exploring different options, I ultimately had to resort to using aggregation in this scenario.

No changes are needed to the schemas.

var results =await dbo.collection('mediators').aggregate([
     { $lookup:
         {
           from: 'venues',
           localField: 'venue',
           foreignField: '_id',
           as: 'venue'
         }
      },
        $match:{$and:[{"venue.venue_type":req.query.venue_type} , {"venue.capacity":{$gte:parseInt(req.query.capacitylb) , $lte:parseInt(req.query.capacityub)}}]}
      },{
        $lookup:
         {
           from: 'users',
           localField: 'user',
           foreignField: '_id',
           as: 'user'
         }
      },{
        $lookup:
        {
           from: 'professionals',
           localField: 'professional',
           foreignField: '_id',
           as: 'professional'
        }
      },{
        $lookup:
        {
          from:'availabilities',
          localField: 'availability',
          foreignField: '_id',
          as: 'availability'
        }
      },{
        $unwind: '$availability'
      },{
        $match:{$and:[{"availability.start":{$lte:new Date(req.query.dateFrom)}},{"availability.end":{$gte:new Date(req.query.dateTo)}}]}
      },{
        $lookup:
        {
          from:'locations',
          localField: 'location',
          foreignField: '_id',
          as: 'location'
        }
      },{
        $project:{
          "_id":1,
          "email":"$user.email",
          "organization_name":"$user.organization_name",
          "website":"$user.website",
          "profile_pic_hash":"$user.profile_pic_hash",
          "bio_hash":"$user.bio_hash",
          "venue_type":"$venue.venue_type",
          "capacity":"$venue.capacity",
          "flat_fee":"$professional.flat_fee",
          "per_participant_fee":"$professional.per_participant_fee",
          "hourly_fee":"$professional.hourly_fee",
          "start_date":"$availability.start",
          "end_date":"$availability.end",
          "distance":"$dist.calculated",
          "location":"$location.location.coordinates",
          "country":"$location.country",
          "city":"$location.city",
          "street":"$location.street",
          "number":"$location.number",
          "zip":"$location.zip"}}

The aggregation code proved to be effective in my case. Special thanks to Anthony Winzlet for the assistance provided.

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

How can I alter an object within an array of a document using a query in Mongoose?

I am working with a data structure: { field: 1, field: 3, field: [ { _id: xxx , subfield: 1 }, { _id: xxx , subfield: 1 }, ] } My task is to update a specific element within the array. Currently, my method involves removing the old obj ...

Tips for correcting the `/Date(xxxxxxxxxxxxx)/` formatting issue in asp.net mvc

As a programming novice, I am trying to display data from my database server on the web using a datatable in asp.net mvc. After following a tutorial video on YouTube, I encountered an issue where the date and time columns in my table are displaying as /Dat ...

What is the best way to discover all available matches?

By utilizing this code snippet, I am able to locate text between specific start and end words. However, the search process stops after the first pair is found. Is there a way to identify all matches? const file = fs.readFileSync('./history.txt', ...

Video player on website experiencing issues with playing VAST ads

Hey there! Check out this awesome site for Music Videos: (Music Videos(Player)) I've been testing different options, but if you have a better suggestion, please let me know. Any help would be really appreciated. If I can't figure it out on my o ...

Imposing the situation

In my current class, I have a private property and a public method for access: Person = function () { this.Name = "asd"; var _public = new Object(); _public.Name = function (value) { if (value == undefined) { //Get return ...

The information returned to the callback function in Angular comes back null

In my Node.js application, I have set up an endpoint like this: usersRoute.get('/get', function(req, res) { //If no date was passed in - just use today's date var date = req.query.date || dateFormat(new Date(), 'yyyy-mm-dd&ap ...

Top recommendation for showcasing a numerical figure with precision to two decimal points

Within my function, I am tasked with returning a string that includes a decimal number. If the number is whole, I simply return it as is along with additional strings. However, if it's not whole, I include the number along with the string up to 2 deci ...

Display validation in HTML5 only when the form is submitted

Here is the code snippet I am referring to: <input required pattern="[0-9]{5,10}" oninput="setCustomValidity('')" oninvalid="setCustomValidity('Type something')" /> I'm looking for a way to remove o ...

Display all data using JSONP

I've encountered an issue with JSONP. Although I was able to successfully load my JSONP data into my html file, I am struggling to display all the information. I have attempted using both a for loop and $.each method without any luck. Here is the JSO ...

Developing a personalized Hook with useRef functionality

Here is a code snippet where I demonstrate creating two custom hooks in React. The first hook, `useChangeText`, utilizes the `useState` hook and works as expected. The second hook, `useGetHTML`, attempts to use `useRef` to log an HTML element to the cons ...

Dynamic Translation Service for Ionic 2 and Angular 2 with ngx-translate

Currently working on an Ionic 2 app and looking to implement object translation directly from the server response instead of using a JSON file. Utilizing ngx-translate Here's an example of the object received: { "name": ["Hello", "Hola", "Bon Jour" ...

Is there a way to deactivate a hyperlink for specific circumstances without relying on pointer events, since they are not compatible with Internet Explorer 8?

Is there a way to deactivate my hyperlink based on specific conditions without relying on pointer events, which are not compatible with IE8? ...

Loading an HTML template dynamically into a pre-loaded div element

I need to dynamically load an HTML template into my index.html file. Now, I am looking to load another HTML template into the previously loaded template content. To clarify further: The index is loaded with a dashboard template, and the dashboard contains ...

Having trouble accessing properties of null (reading 'split'). Please provide a valid prompt

Hey there, I could really use some assistance with an issue I've encountered. Whenever I try to click on "cancel" in a prompt, I keep getting this error message: "Cannot read properties of null (reading 'split')". Basically, all I want is ...

What are the reasons for a jQuery function to run in a selective manner?

There seems to be some inconsistency in the behavior of this incomplete script that I'm trying to debug. The issue arises when I click off an item, as sometimes the $(editObj).removeAttr('style'); line of code executes and other times it doe ...

Why am I encountering http://localhost:3000/api/auth/error?error=AccessDenied when implementing Google signin in my Next.js application?

Can someone please assist me in resolving an issue I am facing with my NextJs application using Google signin? Whenever I try to sign in, I get the error message "http://localhost:3000/api/auth/error?error=AccessDenied". Why is this happening? Here is a ...

Creating a custom calculator using Javascript

As a beginner in Javascript, I am seeking assistance in creating a simple calculator that can add numbers as buttons are clicked and display the running total. For example: If I click the button "20," it should display the number 20. Then, if I click the ...

Discovering the total of varying inputs in ReactJS

//this is the API response: { "message": "success", "code": 100, "data": { "inCourseCategories": [ { "_id": "62b842f09184bf2330e6f506", "course": "601a67e6db65fb15946e6b6f ...

What is the best method for activating a function with @click within an infowindow on Google Maps in Vue.js?

Here's the current code snippet: addpolygon: function(e) { var vm = this; var point = { lat: parseFloat(e.latLng.lat()), lng: parseFloat(e.latLng.lng()) }; vm.coord.push(point); vm.replot(); vm.mark ...

Obtaining the variable from the exec function in Node.js can be achieved by capturing

I am trying to access the values of variables w1 and h1 outside of the exec function and display them using console.log. exec(command, function(err, stdout, stderr) { var resolution = stdout.split("x"); w1 = resolution[0]; h1 = resolution[1]; ...