How to find average using map reduce in MongoDB? - mongodb

My document is of format:
{
"PItems": {
"Workspaces": [
{
"Key": "Item1",
"Size": 228.399,
"Foo": "bar"
},
{
"Key": "Item2",
"Size": 111.399,
"Bar": "baz"
},
{
"Key": "Item2",
"Size": 636.66,
"Baz": "foo"
}
]
}
}
I need to find the average size of each items from all the documents in the collection. How do I do that?
Expected output:
Item1: 346.12
Item2: 563.58
I have tried the following:
db.Resources.mapReduce(
function() {
this.PItems.Workspaces.forEach(
function(z) {
emit(z.Key, z.Size);
}
);
},
function(item, space) {
var total = 0;
for ( var i=0; i<space.length; i++ )
total += size[i];
return { avg : total/space.length };
},
out: { inline: 1 }
);
I am getting a syntax error: SyntaxError: missing ) after argument list. What am I missing here?

Related

How to update jarray in jsonb field?

I have a jsonb field that contained the something like below:
How to update is_read properties in extras node to true where the users_pid = 1 and is_read=false?
I have tried below:
UPDATE chats
SET attributes = jsonb_set(
cast(attributes->'data'->>'extras' AS jsonb),
array['is_read'],
to_jsonb(true)
)
WHERE users_pid =1
AND cast(attributes->'data'->'extras_to'- >>'is_read' AS boolean) = false
but nothing updated
[
{
"data": {
"users_pid": 1,
"datetime": "2022-05-01 13:10:58",
"extras": {
"is_read": false,
"read_dt": ""
}
}
},
{
"data": {
"users_pid": 3,
"datetime": "2022-05-23 11:03:22",
"extras": {
"is_read": false,
"read_dt": ""
}
}
},
{
"data": {
"users_pid": 1,
"datetime": "2022-05-13 11:23:22",
"extras": {
"is_read": false,
"read_dt": ""
}
}
}
]

Search Key in Nested json in Dart/Flutter

I want to search the key "AylaHeartBeatFrequency" inside nested json. how to search and get its value ? in flutter/dart
{
"sAWSIoT": {
"CloudStatus": 1,
"PairingFlag": 0,
},
"sDebug": {
"LocalDebugMsg_d": "Model ID",
"AylaHeartBeatFrequency": 0
},
"Product": {
"Mode": 1,
"Model": "abc"
},
"data": {
"DeviceType": 300,
"Endpoint": 0,
"UniID": "0000000000000000"
}
}
You can do:
var map = /*put your json here. You can use json.decode() on the json if it's not yet formatted*/, value;
for(var item in map.values) {
if(item.containsKey('AylaHeartBeatFrequency') value = item['AylaHeartBeatFrequency']) ;
}

Formatting MongoDB aggregation for Highcharts Stacked Columns

I'm attempting to plot a highcharts stacked column chart displaying multiple button counts per table category. For this I've built the following aggregation in mongodb:
var pipeline = [
{
$group: {
_id: {tableId: "$tableId", buttonId: "$buttonId"},
count: {
$sum: 1
}
}
}
];
This gives me a JSON object with the following hierarchy:
0:
count: 5
_id:
buttonId: "buttonId1"
tableId: "Table1"
I'm trying to bring this into a format suited for highcharts, something along these lines:
var buttonPerTable = [{
name: 'buttonId1',
data: [5, 3, 4]
}, {
name: 'buttonId2',
data: [2, 2, 3]
}, {
name: 'buttonId3',
data: [3, 4, 4]
}]
var tableList = ["Table1","Table2","Table3"]
This is what I've tried, but I can't quite figure out how to do it right, I can't manage to get the data into the wished format:
var activityPerTable = [];
var tableList = [];
result.forEach(function(call, i) {
buttonId = call._id.buttonId
activityPerTable[buttonId] = []
activityPerTable[buttonId].data = []
activityPerTable[buttonId].name = buttonId;
activityPerTable[buttonId].data.push(call.count);
tableList.push(call._id.tableId);
});
tableList = Utils.uniqueArray(tableList);
Any help would be appreciated.
Edit:
Here is a chunk of JSON object:
[
{
"_id": {
"tableId": "table1",
"buttonId": "buttonId1"
},
"count": 1
},
{
"_id": {
"tableId": "table2",
"buttonId": "buttonId3"
},
"count": 10
},
{
"_id": {
"tableId": "table2",
"buttonId": "buttonId1"
},
"count": 12
},
{
"_id": {
"tableId": "table1",
"buttonId": "buttonId2"
},
"count": 8
},
{
"_id": {
"tableId": "table1",
"buttonId": "buttonId2"
},
"count": 2
},
{
"_id": {
"tableId": "table3",
"buttonId": "buttonId1"
},
"count": 3
},
{
"_id": {
"tableId": "table3",
"buttonId": "buttonId2"
},
"count": 6
}
]
It would be a bit simpler if the same names were in order side by side. However, you can convert your JSON to the format required by Highcharts in this way:
Highcharts.each(data, function(el) {
if (series.length) {
for (i = 0; i < series.length; i++) {
if (series[i].name === el._id.buttonId) {
series[i].data.push(el.count);
i = series.length + 1;
}
}
}
if (!series.length || i === series.length) {
series.push({
name: el._id.buttonId,
data: [el.count]
});
}
});
Live demo: http://jsfiddle.net/BlackLabel/tnhv8u62/

group by properties and sum of values between nested json and array of objects

I have users array with their name,
var users = [{'name':'zulekha'}, {'name':'deepika'}];
I am fetching worklogged by each user from jira APIs. So I am getting object like this.
var worklogResult = {
"issues": [
{
"fields": {
"worklog": {
"worklogs": [
{
"author": {
"name": "zulekha",
},
"timeSpentSeconds": 180
},
{
"author": {
"name": "deepika",
},
"timeSpentSeconds": 210
}
]
}
}
},
{
"fields": {
"worklog": {
"worklogs": [
{
"author": {
"name": "deepika",
},
"timeSpentSeconds": 140
}
]
}
}
},
{
"fields": {
"worklog": {
"worklogs": [
{
"author": {
"name": "zulekha",
},
"timeSpentSeconds": 600,
}
]
}
}
},
{
"fields": {
"worklog": {
"worklogs": []
}
}
}
]
}
Now I want to match worklogResult with users in such a way that I can get following output.
output = [{'name':'zulekha','timeSpentSeconds':780}, {'name':'deepika', 'timeSpentSeconds':350}]
Can anyone suggest me how to achieve this?
use _.flatMap to flat nested objects
_.chain(worklogResult.issues)
.flatMap('fields.worklog.worklogs')
.thru(function(spents) {
return _.map(users, function(user) {
return _.merge(user, {
timeSpentSeconds: _.chain(spents)
.filter(['author.name', user.name])
.map('timeSpentSeconds')
.sum()
.value()
})
})
})
.value()

Finding multiple docs using same id not working, using meteor + react and mongoDB

How do I get the email address of the students in the same class_id, take it as there are more then 2 students in different class in the DB as well?
I have this but it return empty array []
Meteor.users.find({"course_learn_list.$.class_id": {$in: [classId]}},
{field: {"emails.address": 1}}
).fetch()
Collections
{
"_id": "LMZiLKs2MRhZiiwoS",
"course_learn_list": [
{
"course_id": "M8EiKfxAAzy25WmFH",
"class_id": "jePhNgEuXLM3ZCt98"
},
{
"course_id": "5hbwrfbfxAAzy2nrg",
"class_id": "dfbfnEuXLM3fngndn"
}
],
"emails": [
{
"address": "student1#gmail.com",
"verified": false
}
]
},
{
"_id": "JgfdLKs2MRhZJgfNgk",
"course_learn_list": [
{
"course_id": "M8EiKfxAAzy25WmFH",
"class_id": "jePhNgEuXLM3ZCt98"
},
{
"course_id": "5hbwrfbfxAAzy2nrg",
"class_id": "dfbfnEuXLM3fngndn"
}
],
"emails": [
{
"address": "student2#gmail.com",
"verified": false
}
]
}
I think you want:
Meteor.users.find({ "course_learn_list.class_id": classId },
{ "course_learn_list.$": 1, "emails.address": 1 }).fetch()
This should find the first instance in each course_learn_list array where the classId is your classId.
In this case you probably don't need to use a projection to get the right answer. Here's an example of extracting the verified email addresses using only the . operator in the selector:
const ids = ['jePhNgEuXLM3ZCt98', 'some-other-id'];
const emails =
Meteor.users.find({ 'course_learn_list.class_id': { $in: ids } })
.fetch()
.map(user => _.findWhere(user.emails, { verified: true }).address);
This works for me!
Meteor.publish("getMyClassStudents", function(classId) {
console.log("Publish getMyClassStudents")
var self = this
if (self.userId) {
var data = Meteor.users.find({
"course_learn_list.class_id": classId
}, {
"fields": {
"emails.address": 1
}
})
return data
}
else {
return self.ready()
}
})