Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to MongoDB aggregation in Node.js

var mongoose = require('mongoose');
var membersModel = require('./model_member.js');
exports.request_friend_list = function(req, res){
var userid=req.body.userid;
console.log(userid);

//  membersModel.find({_id: userid,friends:{status:0}},{_id:0,'friends':1,},function(err,data)
    membersModel.aggregate(
         {$match: {_id:userid}},
         {$project: {friends: 1}},
         {$unwind: "$friends"},
         {$match: {"friends.status": 0}}
     ,function(err,data){
     if(err){
        res.json({status:"error"});
        throw err;
    }else{
        if(JSON.stringify(data).length > 0){
            console.log(JSON.stringify(data));
            res.json(data);
        }
        else{
            res.json({status: "Data is not Exist."});
            console.log("Data is not Exist.");
        }
    }   
});

membersModel.find({...}) is operating normally, but memberModel.Aggregation({...}) is not working. This also works in MongoDB:

db.members.aggregate({$match:_id: ObjectId("532b4729592f81596d000001"),$project:"friends":1,$unwind:"$friends",$match:"friends.status": 0})

What is the problem?

like image 419
user3664775 Avatar asked May 22 '14 11:05

user3664775


People also ask

How aggregation is performed in MongoDB?

In MongoDB, aggregation operations process the data records/documents and return computed results. It collects values from various documents and groups them together and then performs different types of operations on that grouped data like sum, average, minimum, maximum, etc to return a computed result.

Is MongoDB good for aggregation?

As with many other database systems, MongoDB allows you to perform a variety of aggregation operations. These allow you to process data records in a variety of ways, such as grouping data, sorting data into a specific order, or restructuring returned documents, as well as filtering data as one might with a query.

Is MongoDB aggregation fast?

On large collections of millions of documents, MongoDB's aggregation was shown to be much worse than Elasticsearch. Performance worsens with collection size when MongoDB starts using the disk due to limited system RAM. The $lookup stage used without indexes can be very slow.


1 Answers

The likely problem here is that your userid value is not actually a correct ObjectID type when it is being passed into the pipeline. This results in nothing being "matched" in the initial stage.

Therefore as a more complete example:

var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var ObjectID = require("mongodb").ObjectID;

mongoose.connect("mongodb://localhost/test");

friendSchema = new Schema({
  "name": String,
  "status": Number
});

memberSchema = new Schema({
  friends: [friendSchema]
});

var Member = mongoose.model("Members", memberSchema );

var userid = new ObjectID("537ec520e98bcb378e811d54");

console.log( userid );

Member.aggregate([
  { "$match": { "_id": userid } },
  { "$unwind": "$friends" },
  { "$match": { "friends.status": 0 } }],
  function( err, data ) {

    if ( err )
      throw err;

    console.log( JSON.stringify( data, undefined, 2 ) );

  }
);

Which then will match data as expected:

[
  {
    "_id": "537ec520e98bcb378e811d54",
    "friends": [{
      "name": "Ted",
      "status": 0
    }]
  }
]

So be careful to make sure this is of the correct type. The aggregate method does not automatically wrap a string value such as "537ec520e98bcb378e811d54" into an ObjectID type when it is mentioned in a pipeline stage against _id in the way that Mongoose does this with other find and update methods.

like image 57
Neil Lunn Avatar answered Oct 14 '22 02:10

Neil Lunn