I'm struggling to grasp the concept of map-reduce in MongoDB and it's leaving me feeling lost and

I'm currently exploring the potential of map-reduce in order to better grasp its utility.

Within my database, I have a collection titled "actions" containing 100k documents structured like this:

{
    "profile_id":1111,
    "action_id":2222
}

My aim is to conduct some map-reduce examples to generate a list of all users along with the total number of actions each user has taken. Is this achievable? Here's the code snippet I've been using:

db.fbooklikes.mapReduce(
    function(){
        emit(this.profile_id, this.action_id);
    },
    function(keyProfile, valueAction){
        return Array.sum(valueAction);
    },
    {
        out:"example"
    }
)

Unfortunately, this approach isn't producing the desired outcome. The result obtained is as follows:

"counts" : {
    "input" : 100000,
    "emit" : 100000,
    "reduce" : 1146,
    "output" : 13
},
"ok" : 1,
"_o" : {
    "result" : "map_reduce_example",
    "timeMillis" : 2539,
    "counts" : {
        "input" : 100000,
        "emit" : 100000,
        "reduce" : 1146,
        "output" : 13
    },
    "ok" : 1
},

Do you think what I'm attempting to achieve with map-reduce is feasible?

Answer №1

Yes, you can utilize MapReduce, but it may not always be the most efficient option for your task. There are often better tools available for achieving your desired outcome.

While MapReduce can be useful in certain situations, it is typically recommended to use the aggregation framework in MongoDB whenever possible. The introduction of the aggregation framework has provided a more streamlined and optimized approach for data processing:

db.fbooklikes.aggregate([
    { "$group": {
        "_id": "$profile_id",
        "count": { "$sum": 1 }
    }}
])

This simple query will generate counts for all documents in the collection grouped by each unique value of "profile_id".

It's important to note that MapReduce involves JavaScript evaluation, leading to slower performance compared to the native code functions used by the aggregation framework. While MapReduce may still be necessary in some cases, it's advisable to avoid using it for simpler tasks due to its potential drawbacks and complexities:

db.fbooklikes.mapReduce(
    function(){
        emit(this.profile_id, 1);
    },
    function(key,values){
        return Array.sum(values);
    },
    {
        out: { "inline": 1 }
    }
)

An overlooked aspect of MapReduce is how the reducer operates multiple times per emitted key, processing output in chunks until there is only one final value for each key. Ensuring consistency between map and reduce functions is crucial for accurate results.

In general, prioritize using the aggregation framework unless your task demands specialized calculations or complex document traversal that necessitates JavaScript-based processing, in which case MapReduce would be appropriate.

Answer №2

Instead of summing the action ids, you should focus on counting them. To achieve this, consider the code snippet below:

var map = function () {
    emit(this.profile_id, { action_ids : [this.action_id], count : 1  });
}

var reduce  = function(profile_id, values) {
    var value = { action_ids: [], count: 0 };

    for (var i = 0; i < values.length; i++) {
        value.count += values[i].count;
        value.action_ids.push.apply(value.action_ids, values[i].action_ids);
    }

    return value;
}

db.fbooklikes.mapReduce(map, reduce, { out:"example" });

This script will provide an array of action ids along with a count for each profile id. While you could calculate the count by checking the length of the action_ids array, I opted to keep it separate for better clarity in the example.

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

How can I make vuetify carousel arrows unique to my design?

Hey there, I'm currently working with this template in my application: <v-carousel cycle height="300" class="carousel" hide-delimiters> <template v-slot:prev="{ on, attrs }"> < ...

MongoDB's hierarchical database structure model

I am interested in organizing data in a hierarchical manner within MongoDB. For instance, the structure I envision is outlined below: Database1 Datastore1 Collection1 Collection2 Collection3 Collecti ...

Rollup.js with Vue.js displays an HTML comment instead of rendering Vue HTML content

As I delve into the world of Vue.js, I am encountering some challenges with rendering a simple interpolation within my local development application. The Issue Strangely, the Vue instance displays an HTML comment of createElement <body> <sc ...

using v-model in multiple components

Is there a way to simplify this code? <b-address v-model:name="address.name" v-model:addressLine="address.addressLine" v-model:streetNumber="address.streetNumber" v-model:town="address.town" ...

Instructions for sending an array of integers as an argument from JavaScript to Python

I have a JavaScript function that extracts the values of multiple checkboxes and stores them in an array: var selectedValues = $('.item:checked').map(function(){return parseInt($(this).attr('name'));}).get(); My goal is to pass this a ...

Substitute all instances of null bytes

I need to remove null bytes from a string. However, after replacing the null bytes \u0000 in the string let data = {"tet":HelloWorld.\u0000\u0000\u0000\u0000"} let test = JSON.parse(data).tet.replace("\u0000", ""); I always ...

Creating a dynamic number of datasets in Chart JSWith Chart JS

After extensive searching, I thought I was on the verge of finding a solution several times, but unfortunately, no luck! I am aware that a similar question was posted yesterday: React Chartjs, how to handle a dynamic number of datasets, but it remains una ...

"Implementing a function in React to update the state based on target name and value received from

In an attempt to update the state, the current function (handleLabelChange) technically works by updating the state. However, I am looking to dynamically add a name instead of textOne and a value of "????" from the textarea field or another input field. It ...

Troubleshooting Scroll Problems with Angular 5 and PDF.JS

I am working with Angular 5 and PDF.JS. Successfully downloaded a PDF and rendered it. Now, I need to display the PDF in a window by placing it inside a div. <div class="container border"> <div id="OptionsPanel" class="row lighten-1" *ngIf="isLoa ...

How can I effectively monitor entry and exit events in polygons for multiple locations using mongoDB?

In my current project, I am dealing with a large number of vehicles (approximately 2000) and multiple polygons stored in my database using MongoDB. These polygons represent various entities such as cities, countries, intersections, etc., totaling 4 differ ...

How can a single item from each row be chosen by selecting the last item in the list with the radio button?

How can I ensure that only one item is selected from each row in the list when using radio buttons? <?php $i = 1; ?> @foreach ($products as $product) <tr> <td scope="row">{{ $i++ }}</td> <td>{{ ...

Load a new texture dynamically in THREE.JS and GLTF during runtime

I am relatively new to Three.JS and have made progress, but I am in need of assistance. I have successfully loaded a GLTF object into the scene and now I am looking to implement a feature that allows users to customize the object by selecting different te ...

JavaScript allows for the creation of a border around an iframe using the

In order to improve the speed of my search engine, I am implementing lazy loading by using numerous iframes to display various elements of the results. Within the JavaScript code that connects the element ID to the creation of the iframe, I have set the fr ...

A step-by-step guide to setting up a custom splash screen for React Native

Looking for assistance in setting up a splash screen in react-native specifically for Android devices. I've managed to successfully implement one for iOS, but I'm encountering difficulties when it comes to getting one to work on Android. I' ...

NodeJS Jest test failing due to a global variable being set for a different test already

I am currently working on a project in TypeScript using Node.js and Jest. I have a function that may or may not modify a global variable, which is a TypeScript Map. After one test modifies the global variable, it retains that value for subsequent tests. I ...

Using AngularJS to implement ngView within a custom directive

I've been attempting to implement ng-view within a custom directive, but it doesn't seem to be functioning properly and I'm not receiving any console errors. Here's the code for my directive: (function() { 'use strict'; ...

Node.js and TestCafe encountered a critical error: Inefficient mark-compacts were performed near the heap limit, resulting in an allocation failure. The JavaScript heap ran

While executing my test scripts in Node v14.6.0, I encountered the following problem. Here are some of the options I've tried: I attempted to increase the Node Heap Size but unfortunately had no success: export NODE_OPTIONS=--max_old_space_size=4096 ...

Issue encountered: Unable to properly increment the value in Ajax/PHP more than once

I am currently in the process of creating a basic voting system, and as a test run I have set up a div with a PHP variable that should increase by 1 each time a button is clicked. The current setup works fine for one click, but fails to continue incrementi ...

Simplify code by eliminating uuid references

Greetings! I am currently working with some code that is generated within a JSP tag and utilizes the jQuery data function to connect data with a div element. In order to link the jQuery script with the div on the webpage, I have employed a UUID. However, ...

Developing custom events in an NPM package

Developing a basic npm package with signalr integration has been my recent project. Here's how it works: First, the user installs the package Then, the package establishes a connection using signalr At a certain point, the server triggers a function ...