Searching for MongoDB key names for querying and filtering purposes instead of focusing on values

My goal is to search for all keys within a collection that partially match a specific string.

So far, I've only been able to check if a key exists, but it has to be an exact match. Here's the code I've used:

db.collection.find({ "fkClientID": { $exists:1 }})

What I really need is to find all keys that begin with fk instead.

Answer №1

If you want to extract field names from your MongoDB collection using mapReduce, here's how you can achieve that:

To retrieve only the field names at the root level:

db.collection.mapReduce(function () {
    Object.keys(this).forEach(function(key) {
        if (key.match(/^fk/)) emit(key, null);
    });
}, function() {}, { out: { inline: 1 }});

This will provide an output similar to this:

{
    "results": [{
        "_id": "fkKey1",
        "value": null
    }, {
        "_id": "fkKey2",
        "value": null
    }],
    "timeMillis": W,
    "counts": {
        "input": X,
        "emit": Y,
        "reduce": Z,
        "output": 2
    },
    "ok" : 1
}

To get both field names and their values:

db.collection.mapReduce(function () {
    var obj = this;

    Object.keys(this).forEach(function(key) {
        if (key.match(/^fk/)) emit(key, obj[key]);
    });
}, function(key, values) {
    return { values: values };
}, { out: { inline: 1 }});

The results would look like this:

{
    "results": [{
        "_id": "fkKey1",
        "value": {
            "values": [1, 4, 6]
        }
    }, {
        "_id": "fkKey2",
        "value": {
            "values": ["foo", "bar"]
        }
    }],
    "timeMillis": W,
    "counts": {
        "input": X,
        "emit": Y,
        "reduce": Z,
        "output": 2
    },
    "ok" : 1
}

For extracting field names in subdocuments:

In order to fetch field names within subdocuments, consider storing JavaScript functions on the server:

db.system.js.save({ _id: "hasChildren", value: function(obj) {
    return typeof obj === "object";
}});

db.system.js.save({ _id: "getFields", value: function(doc) {
    Object.keys(doc).forEach(function(key) {
        if (key.match(/^fk/)) emit(key, null);
        if (hasChildren(doc[key])) getFields(doc[key])
    });
}});

Don't forget to run db.loadServerScripts() after adding these scripts.

Answer №2

If you are working with the latest version of MongoDB 3.4.4, then utilizing $objectToArray in an aggregate statement alongside $redact is incredibly efficient. This method allows for native operators to be used which results in a very fast processing speed compared to other methods available.

db[collname].aggregate([
  { "$redact": {
    "$cond": {
      "if": {
        "$gt": [
          { "$size": { "$filter": {
            "input": { "$objectToArray": "$$ROOT" },
            "as": "doc",
            "cond": {
              "$eq": [ { "$substr": [ "$$doc.k", 0, 2 ] }, "fk" ]
            }
          }}},
          0
        ]
      },
      "then": "$$KEEP",
      "else": "$$PRUNE"
    }
  }}
 ])

The functionality of $objectToArray which transforms an "object" into key-value pairs in an array format provides great insight into document structure. With the use of $$ROOT, representing the current document object, we can easily extract and examine these key-value pairs.

For obtaining a unique list of matching keys, the optimized approach in MongoDB 3.4.4 would involve:

db[collname].aggregate([
  { "$redact": {
    "$cond": {
      "if": {
        "$gt": [
          { "$size": { "$filter": {
            "input": { "$objectToArray": "$$ROOT" },
            "as": "doc",
            "cond": {
              "$eq": [ { "$substr": [ "$$doc.k", 0, 2 ] }, "fk" ]
            }
          }}},
          0
        ]
      },
      "then": "$$KEEP",
      "else": "$$PRUNE"
    }
  }},
  { "$project": { 
    "j": {
      "$filter": {
        "input": { "$objectToArray": "$$ROOT" },
         "as": "doc",
         "cond": {
           "$eq": [ { "$substr": [ "$$doc.k", 0, 2 ] }, "fk" ]
         }
      }
    }
  }},
  { "$unwind": "$j" },
  { "$group": { "_id": "$j.k" }}
 ])

Alternatively, if certain conditions are met where the key is always present and there is only one occurrence, the aggregation process can be simplified by using $group:

db[colname].aggregate([
  { "$group": { 
    "_id": {
      "$arrayElemAt": [
        { "$map": {
          "input": { "$filter": {
            "input": { "$objectToArray": "$$ROOT" },
             "as": "doc",
             "cond": {
               "$eq": [ { "$substr": [ "$$doc.k", 0, 2 ] }, "fk" ]
             }
          }},
          "as": "el",
          "in": "$$el.k"
        }},
        0
      ]
    }
  }}
 ])

In earlier versions of MongoDB, utilizing the $where syntax was prevalent for evaluating JavaScript expressions. While not the most efficient method due to JavaScript evaluation overhead, it allowed for dynamic analysis of keys within documents:

db[collname].find(function() { return Object.keys(this).some( k => /^fk/.test(k) ) })

This expression can also be structured using standard query syntax as demonstrated below:

db[collname].find({ "$where": "return Object.keys(this).some( k => /^fk/.test(k) )" })

Ultimately, the choice between different approaches depends on the specific requirements of your data model and processing needs.

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

"Incorporate countless Bootstrap 4 carousels into one webpage for an enhanced user

I'm experiencing difficulties with the new Bootstrap 4. Can anyone provide guidance on how to incorporate multiple Bootstrap carousels into a single page? I've researched several websites, but most only offer solutions for Bootstrap 3. Your assi ...

How can I enable a button in a React application when the text input is not populating

For my Instagram MERN project, I have implemented a Comment box feature for users. The Post button starts off disabled and becomes enabled when text is entered. However, despite entering text, the button remains disabled, preventing submission. Below is th ...

What is the Extent of Support for JSON?

What level of support does JSON have across different browsers? I recently tested the following: <?php header('Content-type: application/json'); $arr = array('name' => 'Lisa'); echo json_encode($arr); ?> ...

Having trouble with Redux's mapStateToProps function?

I'm working on a React component that triggers an AJAX call in the componentWillMount lifecycle method and then stores the fetched data in a Redux store. Here's the code snippet: componentWillMount() { var self = this; var xmlhttp = new XMLH ...

Update state within React components without impacting any other state variables

Imagine I have an object structured like this: person : { name : "Test", surname : "Test", age : 40, salary : 5000 currency : "dollar", currency_sign : "$", . . . } I am looking to achieve the following I will make ...

React Component is not functioning with the timer running

I am currently developing a basic timer app using React. Here is the code snippet I have so far: import React from "react" const timer = (props) => { let time = 25; let processStatus = props.timerProcessStatus; // set to true if(processSta ...

The MongoDB replication set encountered an error

In my MongoDB setup, I have a Replica set with three nodes: 1 Primary, 1 Secondary, and 1 Arbiter. During the initial re-sync process from the Primary to the Secondary node, the Primary node unexpectedly terminated. Upon checking the logs, the following e ...

Utilize viewport activation to determine browser width

Is there a way to dynamically add the viewport-meta tag only for devices with screen widths larger than 680px? If the screen is smaller than 680px, then the responsive style file should be enabled instead. I attempted to achieve this by placing the follow ...

position the cursor at the end of the text within the text box

I am looking to move the cursor to the end of the text inside a text box that already contains text. Is there a way to achieve this using Java Script, CSS, or JQuery? <span> <input id="listInput" class="autocomplete-input singleselect-autocom ...

Creating sophisticated TypeScript AngularJS directive

Recently, I came across a directive for selecting objects from checkboxes which can be found at this link: The issue I'm facing is that we are using TypeScript and I am unsure of how to implement the directive in TypeScript. From what I understand, ...

Trigger a keypress event following the activation of a button

I've been trying to simulate the press of the backspace key on the keyboard after clicking a button, but all my attempts have been unsuccessful. Here is the code I'm using: function rtf(){ document.getElementById("u0u").focus(); $('#u0u ...

Hide the Select Column from the material-react-table

Can someone help me with hiding specific columns in the material-react-table component? I've searched the documentation but couldn't find any relevant information. import { useMemo, useState } from "react"; import { MaterialReactTable } ...

Ways to customize the hover effect for react-bootstrap navbar link

I'm looking to update the hover effect color from white to green, but I'm having trouble finding the correct CSS code for it. <Navbar fixed='top' collapseOnSelect expand="md" variant="dark" className="animate ...

How can the checkers code be corrected due to a mistake?

Designed a simple game where the objective is to clear all the pieces by jumping over the checkers. However, encountering an error when attempting to remove the checker for the second time. Uncaught TypeError: Cannot read property 'theRow' of u ...

A guide to efficiently fetch JSON data synchronously using AngularJS

Trying to fetch data from a JSON file using AngularJS results in an error due to the asynchronous nature of the call. The code moves on to the next step before receiving the data, causing issues. The $http.get method was used. $http.get('job.json&apo ...

Error: You forgot to close the parenthesis after the argument list / there are duplicate items

I have already tried to review a similar question asked before by checking out this post, but unfortunately, I still couldn't find a solution for my problem. Even after attempting to add a backslash (\) before the quotation mark ("), specificall ...

Create an array of references

A task I need to complete involves performing a series of steps on an array: First, create an array of references outside the component Next, build a form Within the form, map through the array and render an input for each element When an input is in focu ...

Shorten a data point in JSON code

I'm currently in the process of developing a stock widget that utilizes JSON to retrieve data from the Yahoo API/YQL console. I am specifically working with values extracted from the key ChangePercentRealtime, however, the values are longer than what ...

Exploring ReactJS: Utilizing the useEffect Hook for Retrieving Various Data Sources

I have recently started working with react and currently have a function that fetches data in my useEffect hook. I am using a loading state to handle component rendering, and then populating my state component with the fetched data successfully. However, ...

Using JQuery to Execute Matching Based on Text Within <A> Elements

After reviewing the resources on Jquery Extract URL from Text and jquery match() variable interpolation - complex regexes, I am still a bit confused. The issue at hand is that I have a webpage with a dropdown menu at the top. Inside the dropdown, there ...