What is the best method for searching through all keys of an object?

Multiple documents contain a key called userId, where this key is always an object:


    {
        "id": {
            "$oid": "22fc6b11a0ff111d598b114f"
        },
        "userId": {
            "KEY1"  : ["..."],
            "KEY2"  : ["..."],
            "KEY3"  : ["..."],
            "KEY4"  : ["..."]
        }
    }

Each document will always contain 4 sub-keys, with each being a non-empty array of strings

How can I search through all documents to find strings inside each of these KEY's?

For example:


    /* MONGO document

    {
        "id": {
            "$oid": "65fc6b08a0ffe6dd598b114f"
        },
        "userId": {
            "KEY1"  : ["1", "2", "3"],
            "KEY2"  : ["A", "Z"]
            ...
        }
    },
    {
        "id": {
            "$oid": "22fc6b11a0ff111d598b114f"
        },
        "userId": {
            "KEY1"  : ["4", "5", "6"],
            "KEY2"  : ["Z", "X"]
            ...
        }
    }
    */

    const array = ["2", "X"];
    const users = await db.collection("users").find({ "userId": { "$in": array } }).toArray();
    console.log(users)

const array = ["2", "X"]; <- Specifying an array of strings to find all documents that contain any of these strings in any of the sub-key arrays of the userId object

In this case, it would match both documents, because 2 exists in the first document's userId.KEY1 and X exists in the second document's userId.KEY2

const array = ["X"]; This would match just the second document

My current attempt is not finding any matches, how can I achieve this?

Answer №1

To determine the intersection of the input array with the union of KEY's values, you can utilize $setIntersection combined with $setUnion. It's important to note, however, that this approach may not be optimal as MongoDB needs to construct the Union before performing the intersection check, without utilizing any indexes.

db.collection.find({
  $expr: { $ne: [
    {
      $setIntersection: [
        ["2", "X"],
        { $setUnion: ["$userId.KEY1", "$userId.KEY2", "$userId.KEY3", "$userId.KEY4"] }
      ]
    },
    []]
  }
})

Mongo Playground Link

In cases where there are numerous KEY's, incorporating jQueeny's recommendation of creating a string of $KEY's for the setUnion part is a good fit.

If the number of KEYs is arbitrary and not consistently the same four, you can also utilize $objectToArray as commented by the users:

db.collection.aggregate([
  { $set: { allKEYs: { $objectToArray: "$userId" } } },
  { $match: { "allKEYs.v": { $in: ["2", "X" ] } } },
  { $unset: "allKEYs" }
])

Mongo Playground Link

Similar to the previous method, this also does not utilize any indexes, therefore, jQueeny's approach is recommended for this scenario.

Answer №2

To perform a search query using the $or operator in MongoDB, you can follow this example:

const array = ["2", "X"];
const users = await db.collection("users").find({
  $or: [
    {
      "userId.KEY1": {
        $in: array
      }
    },
    {
      "userId.KEY2": {
        $in: array
      }
    },
    {
      "userId.KEY3": {
        $in: array
      }
    },
    {
      "userId.KEY4": {
        $in: array
      }
    }
  ]
}).toArray();

For a practical demonstration, check out this example.

If you have a large number of keys like KEY1, KEY2...KEY99, you can dynamically create the $or array using a for loop as shown below:

const array = ["2", "X"];
const orArray = [];
const numKeys = 100; // range from KEY1...KEY99
for(i=1; i < numKeys; i++){
  orArray.push(
    {
      [`"userId.KEY${i}"`]: {
        "$in": array
      }
    }
  );
}
const users = await db.collection("users").find({
  $or: orArray
}).toArray();

Answer №3

To achieve your objective, utilize the MongoDB aggregation framework alongside the $or operator and $eleMatch to search through an array of objects.

const array = ["2", "X"];

const user = await db.collection("users").aggregate([
{
$match:{
$or: {
{ "userId.KEY1": { $elemMatch: { $in: array } } },
{ "userId.KEY2": { $elemMatch: { $in: array } } },
{ "userId.KEY3": { $elemMatch: { $in: array } } },
}
}
}
]).toArray();
console.log(users);

This query will find documents where any of the userId sub-keys have at least one element that matches an element in the array

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 jQuery to extract the value of a selected list item on click

I have been working on creating a list of items from JSON data and am facing an issue with retrieving the 'data-value' attribute of the clicked item. Here is my current code: const target = $('#list'); target.empty(); for (let i = 0 ...

Is it possible to prompt npm to install a sub-dependency from a GitHub pull request?

Currently, I'm in the process of setting up geofirestore, which has a dependency on geofirestore-core. However, there is an existing bug in geofirestore-core that has been addressed in a pull request. How can I make sure that my geofirestore installa ...

retrieve content within an iframe via ajax

I currently have an iframe set up on the server side like this: <iframe frameborder="0" runat="server" style="width: 100%; height: 700px; background-color: #bacad3;" id="I1" name="I1" src="Page.aspx"></iframe> and I update the content dynamic ...

Utilizing onMouseEnter and onMouseLeave events in React using hooks

My goal is to create a drop-down menu with a delay, allowing users to hover over the child list items before they disappear. However, I seem to have made an error somewhere but can't pinpoint it. It's likely just a simple mistake that my eyes are ...

Is there a way to insert a value into the input field using JQuery or JavaScript?

After reading my previous post on posting values into an input box, a commenter suggested using JQuery or Javascript. For more code and information, please refer to the link provided above. <label>Date</label>:&nbsp&nbsp <input sty ...

Display array elements without numerical indexes

Consider the code snippet below: for(i=0; i<3; i++){ a = {}; a['name' + i] = i; data.push(a); } This code will generate the following array: { 1:{name0:0}, 2:{name1:1}, 3:{name2:2} } How can I modify the code ...

What is the best way to incorporate a fadeIn animation to a text in jQuery?

Looking for help with appending the fadeIn() jQuery function to a string that increments an integer within a paragraph. I attempted concatenation without success. Any recommendations on how to solve this issue? $p.text(parseInt($p.text(),10) + 1); ...

Arrange objects on a grid

I've got an array filled with objects, each containing 3 images, a name, and some details. I'm attempting to display these objects on Bootstrap cards, but currently each card is showing up on its own line. My goal is to arrange the cards in a gri ...

Using addClass and fadeIn simultaneously when hovering over an element

After writing JavaScript code that utilizes the JQuery library to swap classes on hover, I noticed that the transition between background images was quite abrupt. The code functions as intended, but I would prefer to incorporate a fadeIn and fadeOut effect ...

The issue of sorting in Mongodb is resulting in an undefined

The unsorted data in the leadersList is causing some issues. When attempting to use sort to organize the data, it returns undefined. I am looking for a solution to return the sorted data correctly. app.get('/api/leaders/', async (req, res) => ...

Unable to instantiate FormData with the constructor

Within my Angular application, I have a basic form setup like this: <form [formGroup]="loginForm" (submit)="login()"> <div id="container-credentials"> <input type="text" name="username" formControlName="username"> <input typ ...

How to iterate over the request body in Node.js using Express?

When I send a request with data in the form of an array of objects: [ {id: "1"}, {id: "2"}, {id: "3"} ] I am utilizing JSON.stringify() and my req.body ends up looking like this: { '{"id":"1"} ...

Learn the steps for assigning a distribution tag to an npm package within a private registry

Operating with my own exclusive Gemfury repository, I am actively releasing npm packages. Intrigued by the prospect of applying distribution tags to my packages (as per this guide: https://docs.npmjs.com/cli/dist-tag). The configuration of my npm registr ...

Issue with MUI-table: The alternate rows in the MUI table component are not displaying different colors as intended

Struggling to apply different colors for alternate table rows function Row(props) { const { row } = props; const StyledTableRow = styled(TableRow)(({ theme }) => ({ '&:nth-of-type(odd)': { backgroundColor: "green", ...

Django plugin designed for showing a real-time feed of messages - powered by Dajax or Jquery?

Currently, I am attempting to set up a section in my Django application where updates or messages from the server can be displayed once specific tasks are done. I had initially looked into using a plugin that utilizes Dajax / Jquery for this feature, but ...

Angular 2 404 Error persists despite successful retrieval of data from Oracle database using Backend Nodejs URL entered directly into the browser

Recently, I've been working on displaying data in my Angular frontend that is fetched from an Oracle DB connected to my Node backend. When I access the physical API link, the data appears and is displayed in the backend console.log. I'm wonderin ...

Require assistance to resolve variable scope problems

Having trouble accessing the names array within the driver.executeScript method. Any suggestions on how to resolve this issue? var webdriver = require('selenium-webdriver'), By = webdriver.By, until = webdriver.until; var driver = new webdri ...

Redirecting visitors to a specific section of the website as soon as they enter the site

Currently, I am utilizing a jquery plugin known as Ascensor which can be found at this link: This plugin is designed for creating one-page websites with smooth scrolling capabilities both vertically and horizontally. It operates using a coordinate system ...

How to retrieve the value of an input field in Angular 2/Typescript without using ngModel

Currently, I'm utilizing Typescript in conjunction with Angular2, mirroring the structure of the Angular2 Tour of Heroes guide. There is a specific input field that I aim to associate a change event with, triggering custom logic whenever the value wi ...

React in 2022 has encountered an unexpected expression when it was expecting either an assignment or function call

I am having difficulty updating a chart with values received from an API. I am unsure about how to adjust the useEffect hook in my code. Any advice would be greatly appreciated. Here is a snippet of my code: import React, { useEffect, useState } from &quo ...