I am facing unexpected results while trying to search for a string array object using elemMatch in Mongoose

I am encountering an issue that I can't seem to resolve. I need to utilize a query search to match the data of one job with user data, but I'm facing some obstacles. The primary challenge is within my query search for the job where the data looks like this.

The problem arises in the searchFilterSkills.searchSkillsOffer where I have an array of objects and I aim to match the name of each one if it exists. However, I'm struggling to iterate through them because I receive an array of Strings with .map() which cannot be iterated upon.

After receiving responses from Fabian, if all elements match, it returns the elements as expected. However, I aim for it to return the object if at least one element matches. I attempted using $in, but it didn't work. Is there another query I can use instead of $all?

Below are the data I am trying to search:

"skillsOffer":[
      {
         "name":"Max",
         "rate":0
      },
      {
         "name":"Test",
         "rate":0
      },
      {
         "name":"Javascript",
         "rate":0
      }
   ],
"country":"DEU",
"postalCode":12345

And here are the user data they possess:

"searchFilter" : {
        "remote" : 0,
        "data" : [
            {
                "region" : [
                    "1"
                ],
                "country" : "DEU",
                "searchActive" : false,
                "postalCode" : "123",
                "available" : {
                    "$date" : 1664955924380
                }
            }
        ]
    },
"searchFilterSkills" : {
    "searchSkillsOffer" : [
    {
        "name" : "Javascript",
        "rate" : 100
    },
    {
        "name" : "Test",
        "rate" : 60
    },
    {
        "name" : "Client",
        "rate" : 0
    }
],

}

In skillsOffer, I aim to only search if the name matches without considering the rate. Furthermore, if remote is set to 1, then conduct the above query without the postal code along with remote or the aforementioned one alongside remote.

async searchUsers(req, res, next) {
        const jobID = req.query.jobID;
        let job = await Job.findById(jobID);
        let postalCode = job.postalCode;
        postalCode = postalCode.toString().slice(0, 1);
        let postalCode2 = job.postalCode;
        postalCode2 = postalCode2.toString().slice(0, 2);
        let postalCode3 =  job.postalCode;
        postalCode3 = postalCode3.toString().slice(0, 3);
        let postalCode4 = job.postalCode;
        postalCode4 = postalCode4.toString().slice(0, 4);
        let postalCode5 =  job.postalCode;
        postalCode5 = postalCode5.toString().slice(0, 0);
        let userIds = job.skillsOffer.map(user => user.name).join(", ");
        let users = await User.find({
            "searchFilter.data": {
                $elemMatch: {
                    "$or": [
                        {
                            postalCode: postalCode,
                            
                        },
                        {
                            postalCode: postalCode2,
                        },
                        {
                            postalCode: postalCode3,
                        },
                        {
                            postalCode: postalCode4,
                        },
                        {
                            postalCode: postalCode,
                        },
                        {
                            postalCode: postalCode5,
                        },
        
                    ]
                }
        },
        "searchFilter.data": {
            $elemMatch: {
                country: job.country
            }
        },
    
                    'searchFilterSkills.searchSkillsOffer': {
                    $elemMatch: {
                        name: {
                            $regex: new RegExp(`^${job.skillsOffer.map(jt => jt.name)}`, 'i') 
                        },
                    },

        },
        }); 
        if (job.remote.toString() === "1") {
            users = await User.find({
                "searchFilter.data": {
                    $elemMatch: {
                        "$or": [
                            {
                                postalCode: postalCode,
                                
                            },
                            {
                                postalCode: postalCode2,
                            },
                            {
                                postalCode: postalCode3,
                            },
                            {
                                postalCode: postalCode4,
                            },
                            {
                                postalCode: postalCode,
                            },
                            {
                                postalCode: postalCode5,
                            },
            
                        ]
                    }
            },
            "searchFilter.data": {
                $elemMatch: {
                    country: job.country
                }
            },
    
                "searchFilter.remote": job.remote,
            });
        }

    

        if (!users) {

            res.status(204).json({ error: "No Data" });
            return;
        }
        return res.status(200).send({
            user: users.map(t => 
                t._id
            )
        });
    

    },

Answer №1

If you are looking to match each individual name from the array skillsOffer, you will need to create an $elemMatch object for each name.

The following query can be used in your code to verify if all names are present in the array

searchFilterSkills.searchSkillsOffer
:

{
  'searchFilterSkills.searchSkillsOffer': {
    $all: job.skillsOffer
      .map((user) => user.name)
      .map((name) => ({
        $elemMatch: {
          name: {
            $regex: new RegExp(`^${name}$`, 'i'),
          },
        },
      })),
  },
}

If you want to match any of the names instead, you can use the following code:

{
  $or: job.skillsOffer
    .map((user) => user.name)
    .map((name) => ({
      'searchFilterSkills.searchSkillsOffer': {
        $elemMatch: {
          name: {
            $regex: new RegExp(`^${name}$`, 'i'),
          },
        },
      },
    })),
}

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

jQuery does not change the scroll position of elements

I'm looking to implement a feature on my website where certain points act as "magnets" and when the user is near one of these points, the window automatically scrolls to the top. I found a jQuery plugin that does something similar which you can check ...

When using phonegap with iOS, HTTP requests consistently return a status of 0 when accessing local files

I've encountered an issue while using Phonegap 3.3.0 on iOS. The HTTP request I'm making always returns 0, regardless of whether the file exists or not! var url = './images/pros/imagefile.png'; var http = new XMLHttpRequest(); http.o ...

"Attempting to set headers again after they have already been sent to the client is causing an error

I have been working on a small app that is designed to receive a welcome message through POST and then return it via GET. Everything works fine when I only call one method (either GET or POST), but as soon as I try to use both, I encounter the following er ...

Tips on incorporating "get_template_directory_uri" into a JavaScript function

I am currently working on my WordPress PHP file code, where I have included a JavaScript snippet to display names and images from a query. While the names are being displayed correctly, I am encountering an issue with the images not showing up. After tryi ...

Is it obligatory to reply with status code 200 in Express?

Is it required to explicitly include a status 200 code in the response or is it set automatically? response.json({ status: 'OK', }); vs. response .status(200) .json({ status: 'OK', }); Upon testing the route in my browser, ...

Is there a way to configure Authentication in MongoDB similar to how it is done in traditional SQL databases?

I am looking to secure access to my mongoDB by requiring users to enter a username and password before connecting via the mongo shell. This authentication process ensures that only authorized individuals can login to the database. ...

The mobile menu is not responding to the click event

Upon clicking the mobile menu hamburger button, I am experiencing a lack of response. I expected the hamburger menu to transition and display the mobile menu, but it seems that neither action is being triggered. Even though I can confirm that my javascrip ...

Retrieve the file name of the webpage from the URL bar

Is there a way to retrieve the page name from the address bar using jquery or javascript instead of PHP? I am working on an HTML website and would prefer not to use PHP for this specific task. For example, if the address is www.mywebsite.com/hello.htm, ho ...

Pattern for identifying JavaScript import declarations

My task involves using node to read the contents of a file. Specifically, I am looking to identify and extract a particular import statement within the file that includes the "foo-bar" package. The goal is to match only the line or lines that contain the ...

.bail() function does not function properly when used in conjunction with express-validator

While registering a new user, I require their name, email, and password. If no name is provided, there is no need for the backend to validate the email. I believe that the use of .bail() in express-validator should handle this situation, but unfortunately ...

Timing issues with setInterval and setTimeout are causing them to execute at the incorrect moments

I am struggling with changing the background image using setInterval and setTimeout every x seconds. The issue I am facing is that the timer is not working as intended, causing images to change instantly instead. let images = ['background1.jpg&apo ...

Events in EmberJS that occur after the content has been modified

Need assistance with implementing an alert event for a new tab added to the default ones. Solution: Develop a TabsController Create an initilizerView which uses a list parameter to manage the TabsController.Content Upon insertion of the view, add the ac ...

Increase the CSS integer by a set value at regular intervals with the help of JavaScript

I am looking to create a simulated loading icon that gives the illusion of loading for some calculations, but in reality, it loads quickly. My plan is to increment the animation every second until it appears "complete". I am using CSS3 animations, with a h ...

Next.js is reporting an error where the Schema has not been registered for Mongoose

Recently, I started using next.js and encountered an issue when calling an API with a reference to another document. Mongoose threw an error saying "Schema hasn't been registered for model". Below is the code snippet: Models Task.js // Task Model C ...

javascript assign array to object key

Looking at this basic array: const arr = [ { "id": 2, "color": "red" }, { "id": 1, "color": "blue" }, { "id": 2, "color": "yellow" ...

What is the process for deducting the ordered quantity from the available quantity once an order is confirmed

Although I'm not a fan of hard coding, I've been struggling to find a solution to my problem and some explanations are just not clicking for me. The issue at hand involves three data products in the cart, product details, and placed order data f ...

Looking to transfer data between files in Nodejs

This is the routes.js file I am working with const express = require('express'), router = express.Router(), loginHandler = require('../handler/loginHandler'), router.get('^/:userId/:userType/:sessId/:lang/:orgId/:merchantI ...

Display: Show view once forEach loop finishes execution

I'm facing an issue with my update query execution within a loop. Is there a way to trigger the rendering of a view once the forEach loop completes all its iterations? Here's the snippet of code: conn.query(`SELECT Id, ${sfColumn} from Lead`, ...

Mastering the art of leveraging the raw middleware in the Express framework

I experimented with this block of code: //index.js const express = require("express") const app = express() app.post("/", express.raw(), (req, res) => { console.log(req.body) res.write(req.body.toString()) res.send() }) app.listen(4000) ...

Leveraging the power of ES6 capabilities within the Express.js framework of Node

Recently, I've been experimenting with utilizing ES6 features in Express. Interestingly, I discovered that Nodejs now has built-in support for es6, eliminating the need for babel to transpile my code. Here's a snippet from my app.js file: &apos ...