node-red-contrib-mongodb2
node-red-contrib-mongodb2 copied to clipboard
Isssue withe agregate method.
To reproduce the problem, you have just to follow the tutorial at : https://www.codeproject.com/Articles/1096142/MongoDB-Tutorial-Day-Aggregation
**1 Create the collection **
db.Student.insert({StudentName : "Vijay",Section : "A",Marks:70,Subject:["Hindi","English","Math"]}) db.Student.insert({StudentName : "Gaurav",Section : "A",Marks:90,Subject:["English"]}) db.Student.insert({StudentName : "Ajay",Section : "A",Marks:70,Subject:["Math"]}) db.Student.insert({StudentName : "Ankur",Section : "B",Marks:10,Subject:["Hindi"]}) db.Student.insert({StudentName : "Sunil",Section : "B",Marks:70,Subject:["Math"]}) db.Student.insert({StudentName : "Preeti",Section : "C",Marks:80,Subject:["Hindi","English"]}) db.Student.insert({StudentName : "Anuj",Section : "C",Marks:50,Subject:["English"]}) db.Student.insert({StudentName : "Palka",Section : "D",Marks:40,Subject:["Math"]}) db.Student.insert({StudentName : "Soniya",Section : "D",Marks:20,Subject:["English","Math"]})
**2 Run the following agregate from Node-red **
db.Student.aggregate ([ { "$group": { "_id": { "Section" : "$Section" }, "TotalMarks": { "$sum": "$Marks" }, "Count":{ "$sum" : 1}, "Average" : {"$avg" : "$Marks"} } }, { "$project" : { "SectionName" : "$_id.Section", "Total" : "$TotalMarks" } }, { "$sort":{"SectionName":-1} }, { "$limit" : 2 } ])
**3 if we use the mongodb node we have the good result : an Array of 2 entries **
[{"_id":{"Section":"D"},"SectionName":"D","Total":60},{"_id":{"Section":"C"},"SectionName":"C","Total":130}]
**4 if we use the mongodb2 node we do not have the good result : an Array of 4 entries. It looks like having the $limit operator ignored **
[{"_id":{"Section":"D"},"SectionName":"D","Total":60},{"_id":{"Section":"C"},"SectionName":"C","Total":130},{"_id":{"Section":"B"},"SectionName":"B","Total":80},{"_id":{"Section":"A"},"SectionName":"A","Total":230}]
The mongodb2 simply executes the mongodb command. Please try wrapping your parameters with an array, i.e. doing msg.payload = [...] or even msg.payload = [[...]].
I can confirm this behaviour. It seems like the last part of any given pipeline is ignored. We opted to simply work around this by including an identity projection in the end.
Coming back to this: As @ozomer pointed out msg.payload = [[ ]] should do the trick for aggregate.
This is due to this code:
if ((operation.length > 0) && (args.length > operation.length - 1)) {
// The operation was defined with arguments, thus it may not
// assume that the last argument is the callback.
// We must not pass too many arguments to the operation.
args = args.slice(0, operation.length - 1);
}
The docs in this repo Quite clearly state: _"If you want to pass a single parameter WHICH IS AN ARRAY (eg as with InserMany), wrap your array in an outer array: msg.payload = [[{_id: 1243}, {id: 2345}]]"
This issue should be closed.