Retrieve documents in MongoDB that rely on information from other documents

Consider the following mongoose model:

const UserSchema = Schema({
  //_id: ObjectId,
  //more fields,
  blockedIds: [{
    type: ObjectId,
    ref: 'User'
  }]
})

What would be the most optimal approach to retrieve all users who do not have their _id listed in the blockedIds array of a specific user?

One way to do this could be by executing two separate queries:

User.findById(id).then(user => {
  return User.find({_id: {$nin: user.blockedIds}})
})

Is it feasible to utilize the aggregation framework and $facets in order to achieve this requirement with just one query?

Answer №1

Consider implementing a non-correlated subquery feature from version 3.6 to address your specific use case.

You can try the following code snippet:

User.aggregate(
 [{$lookup:{
   from: "users",
   pipeline:[
    {$match: {_id:mongoose.Types.ObjectId(id)}},
    {$project: {_id:0,blockedIds:1}}
   ],
   as: "noncr"
 }},
 {$match:{
   $expr:{
     $not:[
      {$in:[
        $_id,
        {$arrayElemAt:["$noncr.blockedIds",0]}
      ]}
    ]
  }
}},
{$project:{noncr:0}}]
)

Utilize the $lookup operator to retrieve the "blockedIds" for the specified input id and follow it up with the $match operation to filter out documents where "_id" is not within the list of blockedIds.

The $expr feature enables the utilization of aggregation comparison operators in the $match stage.

Use $arrayElemAt function to extract the first element from the $lookup array.

Employ $in operator to compare the _id against the blockedIds field.

Finally, consider utilizing the $project functionality with exclusion to eliminate the "noncr" field from the resulting output.

Keep in mind to use the collection name instead of the model or schema name when testing the query in the "from" attribute of the lookup stage.

Answer №2

While the aggregation framework mentioned in another response is certainly valuable, it's important to consider all perspectives when designing Redis database structures. By approaching data access from multiple angles and considering ways to invert results, we can come up with alternative solutions.

One such approach involves using a blockedBy array instead of a blockedIds array on the user object:

const UserSchema = Schema({
  blockedBy: [{
    type: ObjectId,
    ref: 'User',
    index: true,
  }]
});

This simple adjustment allows us to rethink the problem and make querying straightforward:

User.find({ userID: { $nin: blockedBy: } });

In certain scenarios, this could prove to be a feasible solution worth considering.

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 there a way to change an ISO 8601 date into the format '/Date(1525687010053)/' using JavaScript?

Is there a way to convert a date value that is formatted as 9999-12-31T00:00:00Z to the format /Date(1525687010053)/ using javascript? I tried implementing the following code, but it doesn't seem to be working: var datevalue = '9999-12-31T00:00 ...

Utilizing recursion and the reduce method for calculating the total of an array elements

Exploring the idea of a recursive function to sum up an array. Here's the array structure I'm experimenting with: [[[1, 2, [[3], 4]], 5, []]] As I delve into learning, I decided to implement it using reduce... and it's been quite successfu ...

Vue2: when passing a function as a prop, a warning will be triggered indicating that the prop has

As a newcomer to Vue, I've been enjoying working with Single File Components. Before diving into my main project idea, I decided to experiment with some small components to get a better grasp of the concept. One such experiment involved creating a co ...

Ways to replace "localhost" with a domain name in a mongodb connection string?

After completing the construction of my website with mongodb, I decided to purchase a domain name. Now, the goal is to modify the connection string by replacing 'localhost' with my new domain name (example.com). The current connection string usin ...

Using a hashtag in the URL to open an HTML <div> element

I have a website with two tabs labeled as Home and Action. When I hover over the Action tab, the URL changes to include #tab_action: https://i.sstatic.net/OOD5S.png Then, when I click on it, the related tab content opens: https://i.sstatic.net/JdcGG.pn ...

Having trouble with transmitting a JSON array to a Node.js server using AJAX

When sending data via AJAX to my nodejs server, I use the following JavaScript on the client side: function login(){ var array=[]; var jsonData={}; jsonData.user=$('#user').val(); jsonData.pass=$('#pass').val(); arr ...

Why won't both routes for Sequelize model querying work simultaneously?

Currently, I am experimenting with different routes in Express while utilizing Sequelize to create my models. I have established two models that function independently of one another. However, I am aiming to have them both operational simultaneously. A sea ...

Halting the HTML-Embedded Video

Currently, I am utilizing a cross-browser embedding method like the following: <video width="549" height="309" controls poster="video/stills/index_demo_videoScreen.jpg" style="margin-top:20px;"> <source src="video/2014-reel-web.mp4" type="vid ...

Guide on populating a table with user input using jQuery and ajax

For the past few days, I've been attempting to populate a table using jQuery and ajax based on search results, but unfortunately, it's not working out for me. Below is the HTML code snippet: <form class="form"> <div class="form-gro ...

Leveraging JavaScript variables conditionally within a JSON object

Within the code snippet below, there is a condition written as (if (epsflag==0)<?php $a=",hide:'true'";?> ). I am looking to achieve the same condition using JavaScript. Essentially, I want to conditionally utilize a JavaScript variable in ...

Error when utilizing the useLocation Hook: "The useLocation() function is only allowed within the scope of a <Router> component" in a React App

Developing a React application has led me to encounter an error while utilizing the useLocation hook from the react-router-dom library. The specific error message reads as follows: Error: useLocation() may be used only in the context of a component. In ...

Alert: Zone.js has identified that the ZoneAwarePromise '(window|global).Promise' has been replaced with polyfills. Kindly address this issue

Recently, I updated my Angular application from version 8 to 9. After updating the packages and successfully compiling the application, I encountered an error message in the Chrome browser console: Error: Zone.js has detected that ZoneAwarePromise `(wind ...

Working with JSON data in AngularJS: A guide to loading data onto a scope variable

I am in the process of developing my personal website where I want to be able to update content easily without having to mess with the HTML code. My approach involves loading and updating a JSON file to achieve this, however, I am currently struggling with ...

Custom control unable to display MP3 file

Hey, I came across this awesome button that I am really interested in using: https://css-tricks.com/making-pure-css-playpause-button/ I'm currently facing two issues with it. First, I can't seem to play the sound. I've placed the mp3 file ...

Tips for navigating to the top of the browser window from the middle or bottom using JavaScript in Protractor

I am in need of clicking the element positioned at the bottom of the page first and then I must click on an element located at the top of the page. In other words, scroll up where it is not visible to the browser. To scroll down, I have used: browse ...

The final piece left in stitching together an array

Issue I have been struggling with this code for some time now and I can't seem to figure out the solution. I am receiving 3 values from inputs and trying to remove all the empty spaces "" in the array, but when I execute the code, it displays the foll ...

What distinguishes between employing a div versus a canvas element for a three.js display?

While it is commonly believed that three.js requires the HTML5 <canvas> element, I have found success in using a simple <div> by assigning height and width properties and then adding the WebGLRenderer.domElement as its child within the HTML str ...

What is the best way to transfer a variable from jQuery to a PHP script?

While I am aware that similar questions have been asked in the past, I am facing a unique challenge in trying to create a table with distinct links and pass the id of the link to a PHP page. Here is what I have so far: echo("<p>To reser ...

How to handle JavaScript exceptions when encountering a null JSON value?

I am receiving data in JSON format using AJAX from an action in Struts 2 for my view. The data consists of a set of information. For example: {"home": "1234", "room": null} When I try to read data.home, I successfully get the value 1234. However, when a ...

Querying MongoDB to find a single alphanumeric zip code located between the specified fields

I have a table called zones in my MySQL database. When I run the query below, it returns the record successfully: SELECT * FROM zones WHERE zone_structure_id = 2 AND country_code='CA' AND 'B2H5E1' between from_postal ...