Navigating through MongoDB's MapReduce feature to access Associative Arrays/Objects

Seeking to compile a list of users on a blog who have replied to each other. The data contains:

{
    "_id" : ObjectId("4ee9ada4edfb941f3400ba63"),
    "thread" : "Millenium - Niels Arden Oplev",
    "author" : "kilny17",
    "parent_count" : 0,
    "parents" : [ ],
    "child_count" : 2,
    "date" : ISODate("2010-04-20T21:14:00Z"),
    "message" : "I don't think so...",
    "children" : [
            {
                    "date" : ISODate("2010-04-20T21:21:00Z"),
                    "author" : "Kissoon"
            },
            {
                    "date" : ISODate("2010-04-20T21:49:00Z"),
                    "author" : "Twain"
            }
    ]
}

Want to generate a MapReduced object for each author like this:

{ "_id" : "kilny17",
"value" : { 
    "author" : "kilny17", 
    "connections" : {
          "Kissoon" : 1, 
          "Twain" : 1 }
    } 
}

The code successfully handles records with one child, but encounters issues with multiple children:

    function mapf()
    {   
        var count = this['child_count'];

        if (count > 0){
            var m_author = this.author;

            this['children'].forEach( function(c){

                    var connect = {'name':c['author'], 'appears':1};
                    emit(m_author, {'author':m_author, 'connections':connect});                   
            });
        };           
    }

    function reducef(key, values)
    {   
        var connects = new Object();          
        var r = {'author':key, 'connections':connects, 'weight':0};

        values.forEach(function(v)
        {   
            c_name = v['connections'].name;
            if (c_name == null)
                c_name = 'Null_name';

            if (r['connections'][c_name] != null)
                r['connections'][c_name] += v['connections']['appears'];
            else
                r['connections'][c_name] = v['connections']['appears'];

        });

       return r;        
    }

When handling records with more than one child, the author names are not captured resulting in reduced records like this:

 { "_id" : "kilny17", "value" : { "author" : "kilny17", "connections" : { "DarkKnight3657" : 1, "Null_name" : null } } }

Looking for suggestions on why the author names are not being retrieved correctly from the Object.

Thank you

Answer №1

In my opinion, the issue lies in how you are declaring connections in the mapper - instead of defining it as an array, you have defined it as an element. Upon initial evaluation, it appears that the correct way to define it is:

var connect = [{'name':c['author'], 'appears':1}];
emit(m_author, {'author':m_author, 'connections':connect});

Answer №2

After receiving Chris's suggestion, I implemented a solution that involved transforming the object into an array:

    function updateMap()
    {   
        if (this['child_count'] > 0){

            var main_author = this.author;
            if ( main_author == '')
                main_author = 'Unknown_author';

            var connectionsArray = [];
            var totalWeight = 0;

            for ( child in this['children'] ){
                child_name =  this['children'][child]['author'];
                found = false;
                for (index in connectionsArray){
                    if (connectionsArray[index]['name'] == child_name){
                        connectionsArray[index]['appears'] += 1;
                        found = true;
                    }
                }
                if (found == false){
                   var connection = {'name':child_name,'appears':1};
                   connectionsArray.push(connection);
                }
                totalWeight += 1;
            };       
            emit(main_author, {'author':main_author, 'connections':connectionsArray, 'weight':totalWeight});
        };
    }

    function aggregate(key, values)
    {   
        var result = {'author':key, 'connections':[], 'weight':0};

        values.forEach(function(val)
        {   
            for ( child in val['connections'] ){
                child_name =  val['connections'][child]['name'];
                found = false;
                for (index in result['connections']){
                    if (result['connections'][index]['name'] == child_name){
                        result['connections'][index]['appears'] += 1;
                        found = true;
                    }
                }
                if (found == false){
                   var connection = {'name':child_name,'appears':1};
                   result['connections'].push(connection);
                }
            };
            result.weight += val.weight;
        });
       return r;
    }

As a result, the desired type of records were generated:

{
    "_id" : "Skaundee",
    "value" : {
            "author" : "Skaundee",
            "connections" : [
                    {
                            "name" : "Carnage",
                            "appears" : 1
                    },
                    {
                            "name" : "Tree",
                            "appears" : 1
                    }
            ],
            "weight" : 2
    }
}

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 it possible to retrieve a variable from outside a `.then` block within a promise?

I'm currently developing a Spotify application. I've successfully implemented the login functionality and obtained my token. However, I have encountered an issue where I am unable to access a specific variable outside of a method, in this case be ...

Ensuring the presence of Objects/Functions in different browsers using javascript

I am seeking advice on the best practices for testing object existence for cross-browser compatibility. There are numerous methods available for testing whether an object/function/attribute exists. While I could utilize jQuery or another library, my prefe ...

What steps should I follow to design a unique select element using divs?

In my process of creating a unique custom design, I opted not to utilize a select element. Instead, I attempted to retrieve the value in handleSubmit(), but it kept displaying as undefined in the console. https://i.sstatic.net/xZLuo.png const handleS ...

Executing Multiple Ajax Requests in Jquery

I have a jQuery script that is designed to submit data to the database: //delegated submit handlers for the forms inside the table $('#issue').on('click', function (e) { ...

Organizing your project with VueJS, VuelidateJS, and NodeJS/Express for optimal structure

Primarily, I specialize in developing intranet sites and web front-ends for embedded devices using NodeJS. Currently, all my code is contained within one NPM package. I have NodeJS running behind Nginx, allowing Nginx to serve css/image/client-side-javasc ...

Problem encountered with sending automated responses in Discord bot for updates on current events

Issue with Automated Replies in Discord.js' Functionality I'm currently developing a Discord bot using the Discord.js library in Node.js, and I've encountered a problem with the automatic replies feature. The bot's main task is to retr ...

Discover the world of Google Chrome Apps with the power of chrome.storage.local

While building an application, I encountered a perplexing issue that I need help with: The task involves reading a JSON file and storing its content in localStorage using chrome.storage.local in a Chrome app. Here is a snippet from the JSON file: { "s ...

Unable to retrieve content with Beautiful Soup and Selenium

When attempting to extract data from apartments.com, I encountered an issue with BeautifulSoup not being able to retrieve dynamic content. After some research, it became clear that using Selenium was necessary for loading dynamic content. Despite implemen ...

Guide to discovering an almost ascending sequence in an Array

I recently encountered a challenging algorithm problem that I need help with: "I have a sequence of integers stored in an array. My task is to determine whether it is possible to obtain a strictly increasing sequence by removing no more than one element f ...

The functionality of nested dynamic routing in the API is experiencing issues

Looking to extract product details from a specific category of products? My folder structure appears as follows: https://i.stack.imgur.com/1UCy3.png In "productId/index.jsx" => This snippet is utilized to retrieve individual product details: ...

A step-by-step guide to identifying the clicked bar on a Chart.js graph

When using Chart JS to create a line bar chart, I am looking to specifically identify which bar was clicked on the chart and determine the index of that bar. This will allow me to display specific details for each clicked bar on a table. For example, click ...

Executing multiple HTTP requests in parallel with AXIOS and retrieving the responses even if one of the requests fails

I am currently working on optimizing server get requests to run concurrently. To achieve this, I have developed the following function. Issue The problem arises when one request fails, causing me to lose track of the responses from the other requests. e ...

`Designing a UI in Ionic version 2`

Is it possible to create a layout page in an Ionic v2 application so that the navbar and sidemenu can be displayed on every page without having to add them individually to each page? For example, ASP.NET uses master pages for websites to contain component ...

alter URL parameters dynamically during API invocation

Is there a way to call an API multiple times in one request? I need the ability to dynamically adjust the date parameters for each call so that I can retrieve data for different days simultaneously. While conducting research, I came across the following c ...

What is the best way to pause before executing the next npm command until the current command finishes running?

At first glance, creating an 'init' command seems like a straightforward task. However, as I dive deeper into the process, challenges start to surface. The goal is to develop an 'init' command that assists in preparing a cloned repo fo ...

The characteristics that define an object as a writable stream in nodejs

Lately, I've been delving into the world of express and mongoose with nodejs. Interestingly, I have stumbled upon some functionality that seems to work in unexpected ways. In my exploration, I noticed that when I create an aggregation query in mongoos ...

Associating a mouse click with elements within a repetitious function

Currently, I am importing children of element with ID #parentEle, creating a duplicate of each child and adding it to an array with a new ID - #eleCopy(i). I am facing an issue where I am trying to implement a click function on the original imported objec ...

Transforming data from an HTML form into a PDF document - Tips for generating multiple outputs

As a newcomer to coding, I am facing a challenge in passing input data from a form to a PHP response page and then displaying it in the browser. I have created a functionality where the user can click on a button to save the HTML element to PDF. However, I ...

Trouble with jQuery when trying to animate the loading of a new page into a div

I'm trying to create a smooth transition effect where a div containing a PHP page fades out, unloads, and then fades in a new page every time a menu item is clicked: $('#home').click(function() { $('#page_container&apos ...

Step-by-step guide on resolving AngularJS Issue: [$injector:modulerr]

I'm encountering an issue with Angular JS where I'm receiving the following error: jquery.js:7993 Uncaught Error: [$injector:modulerr] Failed to instantiate module application due to: Error: [$injector:nomod] Module 'application' is no ...