GroupBy array of objects to new array and sum value - javascript

I have a array like this in below, What I'm trying is seperating objects to new array by grouping two values.
Array:
[
{
"year": "202003",
"cost": 11194.55,
"type": "A"
},
{
"year": "202003",
"cost": 60.2,
"type": "B"
},
{
"year": "202003",
"cost": 747.12,
"type": "C"
},
{
"year": "202003",
"cost": 747.12,
"type": "D"
},
{
"year": "202004",
"cost": 747.12,
"type": "D"
},
{
"year": "202003",
"cost": 4674.59,
"type": "D"
}
]
Result should be like this;
Output
[
[
{
"year": "202003",
"cost": 11194.55,
"type": "A"
}
],
[
{
"year": "202003",
"cost": 60.2,
"type": "B"
}
],
[
{
"year": "202003",
"cost": 747.12,
"type": "C"
}
],
[
{
"year": "202003",
"cost": 1494.24, // sum of the COST value when year and type same.
"type": "D"
},
{
"year": "202004",
"cost": 4674.59,
"type": "D"
}
]
];
What I've tried
<script src="//cdnjs.cloudflare.com/ajax/libs/linq.js/2.2.0.2/linq.min.js"></script>
let aggregatedObject = Enumerable.From(data)
.GroupBy("$.type", "$.year",
function (key, g) {
return {
label: key,
value: g.Sum("$.cost"),
}
})
.ToArray();
How can I group this data like this? Is there any library or a function to do this? I couldn't find yet.
Any help will be highly appreciated!

Looking at your initial array and the output you wanted to get, below are the examples that result in exactly the same structure as per your question - an array of arrays of objects
One way with find & for of loop:
let arr = [
{
"year": "202003",
"cost": 11194.55,
"type": "A"
},
{
"year": "202003",
"cost": 60.2,
"type": "B"
},
{
"year": "202003",
"cost": 747.12,
"type": "C"
},
{
"year": "202003",
"cost": 747.12,
"type": "D"
},
{
"year": "202004",
"cost": 747.12,
"type": "D"
},
{
"year": "202003",
"cost": 4674.59,
"type": "D"
}
]
let sortedArray = []
for (let [index, el] of arr.entries()) {
if(sortedArray.find(elInner => (elInner[0].type === el.type && elInner[0].year !== el.year))) {
sortedArray.find(elInner => elInner[0].type === el.type).push(arr[index])
}else if (sortedArray.find(elInner => (elInner[0].type === el.type && elInner[0].year == el.year))) {
sortedArray.find(elInner => (elInner[0].type === el.type && elInner[0].year == el.year))[0].cost += arr[index].cost
}else {
sortedArray.push([el])
}
}
console.log(sortedArray)
and another "cleaner" way with reduce & map
let arr = [
{
"year": "202003",
"cost": 11194.55,
"type": "A"
},
{
"year": "202003",
"cost": 60.2,
"type": "B"
},
{
"year": "202003",
"cost": 747.12,
"type": "C"
},
{
"year": "202003",
"cost": 747.12,
"type": "D"
},
{
"year": "202004",
"cost": 747.12,
"type": "D"
},
{
"year": "202003",
"cost": 4674.59,
"type": "D"
}
]
let sortedArray = arr.reduce((acc, obj) => {
const key = obj.type, year = obj.year
!!acc[key]
? (!!acc[key][year] ? acc[key][year].cost += obj.cost : acc[key][year] = obj)
: (acc[key] = [], acc[key][year] = obj)
return acc
}, [])
sortedArray = Object.values(sortedArray).map((val) => Object.values(val))
console.log(sortedArray)

You can use Array.reduce in order to accumulate the cost.
const data = [
{
year: '202003',
cost: 11194.55,
type: 'A',
},
{
year: '202003',
cost: 60.2,
type: 'B',
},
{
year: '202003',
cost: 747.12,
type: 'C',
},
{
year: '202003',
cost: 747.12,
type: 'D',
},
{
year: '202004',
cost: 747.12,
type: 'D',
},
{
year: '202003',
cost: 4674.59,
type: 'D',
},
];
const final = data.reduce((result, current) => {
const key = `${current.year}-${current.type}`;
result[key] = result[key] || {...current, cost: 0};
result[key].cost += current.cost;
return result;
}, {});
console.log(Object.values(final).map(item => ([item])));

You can try to use array.reduce instead of linq.js, every callback execution accumulates the data if there's matching year and type or adds a copy of an object to an array which is returned from the function:
let data = [
{
"year": "202003",
"cost": 11194.55,
"type": "A"
},
{
"year": "202003",
"cost": 60.2,
"type": "B"
},
{
"year": "202003",
"cost": 747.12,
"type": "C"
},
{
"year": "202003",
"cost": 747.12,
"type": "D"
},
{
"year": "202004",
"cost": 747.12,
"type": "D"
},
{
"year": "202003",
"cost": 4674.59,
"type": "D"
}
];
let aggregatedObject = data.reduce((acc,cur) => {
let prev = acc.find(x => x.year === cur.year && x.type === cur.type);
if(!prev){
acc.push([{...cur}]);
} else {
prev.cost += cur.cost;
}
return acc;
}, []);
console.log(aggregatedObject);

You could take a joined key with linq as forth parameter and a combined object for getting a summed value.
var data = [{ year: "202003", cost: 11194.55, type: "A" }, { year: "202003", cost: 60.2, type: "B" }, { year: "202003", cost: 747.12, type: "C" }, { year: "202003", cost: 747.12, type: "D" }, { year: "202004", cost: 747.12, type: "D" }, { year: "202003", cost: 4674.59, type: "D" }],
result = Enumerable
.From(data)
.GroupBy(
null,
null,
"{ year: $.year, cost: $$.Sum('$.cost'), type: $.type }",
"$.year + '|' + $.type"
)
.ToArray();
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/linq.js/2.2.0.2/linq.js"></script>

Related

filtering an array based on another array based on the order

I have two arrays one is selectedOption and another is defaultOption, if the selectedOption id is present in any of the defaultOption array option property then it will be replaced with the current one . For an example i have added the expected_output
How could i achieve the expected output
let selectedOption = [
{
"count": 12,
"id": "16",
},
{
"count": 3,
"id": "4",
},
{
"count": 2,
"id": "8",
},
{
"count": 4,
"id": "15",
},
{
"count": 1,
"id": "6",
},
{
"count": 34,
"id": "19",
}
]
let defaultOption = [
{
"item_select": {
"value": "16",
},
"options": []
},
{
"item_select": {
"value": "4",
},
"options": [
{
"value": "4"
},
{
"value": "5"
},
{
"value": "6"
},
{
"value": "7"
}
]
},
{
"item_select": {
"value": "8",
},
"options": [
{
"value": "8"
},
{
"value": "9"
},
{
"value": "10"
},
{
"value": "11"
}
]
},
{
"item_select": {
"value": "12",
},
"options": [
{
"value": "12"
},
{
"value": "13"
},
{
"value": "14"
},
{
"value": "15"
}
]
}
]
What I have tried so far
let expected_output = []
selectedOption.forEach(current => {
isDefaultOptionMatched = defaultOption.find(defOpt => defOpt.options.some(opt => opt.value === current.id))
if(isDefaultOptionMatched?.options){
let allMatches = selectedOption.filter(selOpt => {
defaultOption.some(defOption => defOption.options.find(dop => dop.value === selOpt.id))
})
expected_output.push(allMatches[allMatches.length - 1])
}else{
expected_output.push(current)
}
})
What I am getting is 6 elements instead of 5, and its not right.
expected output what I am looking
Instead of 6 objects of expected_output array it will be 5 objects because the second last object id => 6 is part of defaultOption[1].options. The element which got removed is.
{
"count": 3,
"id": "4",
},
Which is part of defaultOption[1].options
expected_output = [
{
"count": 12,
"id": "16",
},
{
"count": 2,
"id": "8",
},
{
"count": 4,
"id": "15",
},
{
"count": 1,
"id": "6",
},
{
"count": 34,
"id": "19",
}
]
Any help is appreciated
Here's a semi-hacky approach (I don't like bucketing the items and remembering the order to rebuild the array later) but it works
let selectedOption = [
{
"count": 12,
"id": "16",
},
{
"count": 3,
"id": "4",
},
{
"count": 2,
"id": "8",
},
{
"count": 4,
"id": "15",
},
{
"count": 1,
"id": "6",
},
{
"count": 34,
"id": "19",
}
];
let defaultOption = [
{
"item_select": {
"value": "16",
},
"options": []
},
{
"item_select": {
"value": "4",
},
"options": [
{
"value": "4"
},
{
"value": "5"
},
{
"value": "6"
},
{
"value": "7"
}
]
},
{
"item_select": {
"value": "8",
},
"options": [
{
"value": "8"
},
{
"value": "9"
},
{
"value": "10"
},
{
"value": "11"
}
]
},
{
"item_select": {
"value": "12",
},
"options": [
{
"value": "12"
},
{
"value": "13"
},
{
"value": "14"
},
{
"value": "15"
}
]
}
];
const result =
selectedOption.reduce((acc, el, order) => {
// bucket each element based on where it's found in defaultOption
const def = defaultOption.find(el2 => el2.options.some(el3 => el3.value === el.id));
if (def) {
const defId = def.item_select.value;
acc[defId] = {...el, order};
} else {
acc[el.id] = {...el, order};
}
return acc;
}, {});
// fix the order and remove the order field
const finish = Object.values(result).sort((a, b) => a.order - b.order).map(({order, ...rest}) => rest);
console.log(finish);
let selectedOption = [
{
"count": 12,
"id": "16",
},
{
"count": 3,
"id": "4",
},
{
"count": 2,
"id": "8",
},
{
"count": 4,
"id": "15",
},
{
"count": 1,
"id": "6",
},
{
"count": 34,
"id": "19",
}
]
let defaultOption = [
{
"item_select": {
"value": "16",
},
"options": []
},
{
"item_select": {
"value": "4",
},
"options": [
{
"value": "4"
},
{
"value": "5"
},
{
"value": "6"
},
{
"value": "7"
}
]
},
{
"item_select": {
"value": "8",
},
"options": [
{
"value": "8"
},
{
"value": "9"
},
{
"value": "10"
},
{
"value": "11"
}
]
},
{
"item_select": {
"value": "12",
},
"options": [
{
"value": "12"
},
{
"value": "13"
},
{
"value": "14"
},
{
"value": "15"
}
]
}
]
let expected_output = []
defaultOption.forEach(defOption => {
let allMatches = selectedOption.filter(selOpt => defOption.options.find(dop => dop.value === selOpt.id))
if(allMatches.length > 0){
expected_output.push(allMatches[allMatches.length - 1])
}
})
selectedOption.forEach(selOpt => {
let isDefaultOptionMatched = defaultOption.find(defOpt => defOpt.options.some(opt => opt.value === selOpt.id))
if(!isDefaultOptionMatched){
expected_output.push(selOpt)
}
})
console.log(expected_output)

Using undescore.js, i'm trying to format the given input to an expected output

Input:
[{
"dimensions": [{
"name": "Size",
"value": "Size1"
},
{
"name": "Color",
"value": "Color1"
},
{
"name": "Pattern",
"value": "1"
}
],
"link": "link",
"title": "title"
},
{
"dimensions": [{
"name": "Size",
"value": "Size2"
},
{
"name": "Color",
"value": "Color1"
},
{
"name": "Pattern",
"value": "2"
}
],
"link": "link1",
"title": "title"
},
{
"dimensions": [{
"name": "Size",
"value": "Size1"
},
{
"name": "Color",
"value": "Color2"
},
{
"name": "Pattern",
"value": "1"
}
],
"link": "link",
"title": "title"
},
{
"dimensions": [{
"name": "Size",
"value": "Size2"
},
{
"name": "Color",
"value": "Color1"
},
{
"name": "Pattern",
"value": "3"
}
],
"link": "link",
"title": "title"
}]
Expected Output:
{
"levels":3,
"level_1_name":"Size",
"level_2_name":"Color",
"level_3_name":"Pattern",
"data":[
{
"value":"Size1",
"data":[
{
"value":"Color1",
"data":[
{
"value":"1"
}
]
}, {
"value":"Color2",
"data":[
{
"value":"4"
}
]
}
]
}, {
"value":"Size2",
"data":[
{
"value":"Color1",
"data":[
{
"value":"3"
}
]
},
{
"value":"Color2",
"data":[
{
"value":"2"
}
]
}
]
}
]
}
I've tried something like that
for(index=0; index<data[0].dimensions.length - 1; index++) {
let temp = _(data).groupBy(function(o) {
return o.dimensions[index].value
})
let keys = Object.keys(temp)
addData(final, keys, temp)
}
obj["data"] = final
function addData(data, keys, temp) {
if (data && data.length) {
return data.forEach(function(data1){
console.log(data1)
return addData(data1, keys, temp)
})
} else {
let data_arr = []
if (Array.isArray(data)) {
keys.forEach(function(key) {
data.push({
value: key,
data: temp[key]
})
})
} else {
keys.forEach(function(key) {
let data_obj = {}
data_obj['value'] = key
data_obj['data'] = temp[key]
data_arr.push(data_obj)
})
data["data"] = data_arr
}
}
}
I've tried the logic to format as per the expected output. It works with level 2 input set, But the logic written doesn't work for level 3 input data set.
Also It would be helpful if you can suggest any algorithms to sort this problem out.
Thanks in advance!
Here is a fairly compact solution using reduce(). (I've edited the input to match your expected output.)
const source = [{
"dimensions": [{
"name": "Size",
"value": "Size1"
},
{
"name": "Color",
"value": "Color1"
},
{
"name": "Pattern",
"value": "1"
}
],
"link": "link",
"title": "title"
},
{
"dimensions": [{
"name": "Size",
"value": "Size2"
},
{
"name": "Color",
"value": "Color2"
},
{
"name": "Pattern",
"value": "2"
}
],
"link": "link1",
"title": "title"
},
{
"dimensions": [{
"name": "Size",
"value": "Size1"
},
{
"name": "Color",
"value": "Color2"
},
{
"name": "Pattern",
"value": "4"
}
],
"link": "link",
"title": "title"
},
{
"dimensions": [{
"name": "Size",
"value": "Size2"
},
{
"name": "Color",
"value": "Color1"
},
{
"name": "Pattern",
"value": "3"
}
],
"link": "link",
"title": "title"
}];
const output = source.reduce((acc, {dimensions: dims}) => {
const levels = dims.length;
// initialize top-level keys based on first object
if (!acc.hasOwnProperty('levels')) {
acc.levels = levels;
dims.forEach((level, i) => acc[`level_${i+1}_name`] = level.name);
acc.data = [];
}
// iterate over dimension objects and merge with accumulator
let parent = acc.data;
dims.forEach((o, i) => {
let lvlObj = parent.find(e => e.value === o.value);
if (!lvlObj) {
lvlObj = i < levels - 1 ?
{value: o.value, data: []} :
{value: o.value};
parent.push({...lvlObj});
}
parent = lvlObj.data;
});
return acc;
}, {});
console.log(output);

How to traverse data according to an array?

I am trying to traverse the data according to the show array and print the data to see if it is correct. To traverse the list array corresponding to the show array as follows
I want the effect as follows:
[
{
"name": "A",
"age": "10",
},
{
"name": "B",
"age": "20",
}
]
const data = [{
"code": "200",
"msg": "success",
"data": {
"list": [{
"name": "A",
"age": "10",
"logo": "aa.png",
"note": "aa"
}, {
"name": "B",
"age": "20",
"logo": "bb.png",
"note": "bb"
}],
"show": [
"name",
"age"
]
}
}]
function init() {
data.map(res => {
if (res.code == 200) {
console.log(res.data.list)
}
})
}
init();
By iterating show (rather than hard-coding name and age), this code would work also if you change the structure of your template:
const data = [{
"code": "200",
"msg": "success",
"data": {
"list": [{
"name": "A",
"age": "10",
"logo": "aa.png",
"note": "aa"
}, {
"name": "B",
"age": "20",
"logo": "bb.png",
"note": "bb"
}],
"show": [
"name",
"age"
]
}
}];
var ans = data[0].data.list.map(item => {
var curr = {};
data[0].data.show.forEach(prop => {
curr[prop] = item[prop];
});
return curr;
});
console.log(ans);
You can use reduce in a shorter way:
const data = [
{
code: "200",
msg: "success",
data: {
list: [
{
name: "A",
age: "10",
logo: "aa.png",
note: "aa"
},
{
name: "B",
age: "20",
logo: "bb.png",
note: "bb"
}
],
show: ["name", "age"]
}
}
];
console.log(data[0].data.list.map(x =>
data[0].data.show.reduce((p, c) => ((p[c] = x[c]), p), {})
));
const data = [{
"code": "200",
"msg": "success",
"data": {
"list": [{
"name": "A",
"age": "10",
"logo": "aa.png",
"note": "aa"
}, {
"name": "B",
"age": "20",
"logo": "bb.png",
"note": "bb"
}],
"show": [
"name",
"age"
]
}
}];
function init() {
data.map(res => {
if (res.code == 200) {
console.log(res.data.list.map(function(listValue) {
var ret = {};
res.data.show.forEach(function(idx) {
ret[idx] = listValue[idx]
});
return ret;
}));
}
})
}
init();
You can use .map on your data and return false if the code isn't 200, if it is 200, you can return a mapped version of your list array. You can map this array to a subset of each object in your list. The subset is defined by your show array, and so you can use .reduce() on this array to build your mapped object.
See example below:
const data = [{
"code": "200",
"msg": "success",
"data": {
"list": [{
"name": "A",
"age": "10",
"logo": "aa.png",
"note": "aa"
}, {
"name": "B",
"age": "20",
"logo": "bb.png",
"note": "bb"
}],
"show": [
"name",
"age"
]
}
}];
function init() {
return data.map(res => {
if (res.code == 200) {
return res.data.list.map((obj) => {
return res.data.show.reduce((acc, prop) => ({...acc, [prop]: obj[prop]}), {});
});
}
return false;
}).filter(Boolean); // filter out any `false` returns
}
console.log(init());
Alternatively, a better approach than mapping your original data would be to use .reduce(). This will create a one-dimensional array of results:
const data = [{
"code": "200",
"msg": "success",
"data": {
"list": [{
"name": "A",
"age": "10",
"logo": "aa.png",
"note": "aa"
}, {
"name": "B",
"age": "20",
"logo": "bb.png",
"note": "bb"
}],
"show": [
"name",
"age"
]
}
},
{
"code": "200",
"msg": "success",
"data": {
"list": [{
"name": "C",
"age": "30",
"logo": "aa.png",
"note": "aa"
}, {
"name": "D",
"age": "40",
"logo": "bb.png",
"note": "bb"
}],
"show": [
"name",
"age"
]
}
}];
function init() {
return data.reduce((acc, res) => {
if (res.code == 200) {
return [...acc, ...res.data.list.map((obj) => {
return res.data.show.reduce((acc, prop) => ({...acc, [prop]: obj[prop]}), {});
})];
}
return acc;
}, []);
}
console.log(init());
If you want to show only name and age as
[
{
"name": "A",
"age": "10",
},
{
"name": "B",
"age": "20",
}
]
Array.map can be used
and then you can write your code this way
const data = [
{
code: '200',
msg: 'success',
data: {
list: [
{
name: 'A',
age: '10',
logo: 'aa.png',
note: 'aa'
},
{
name: 'B',
age: '20',
logo: 'bb.png',
note: 'bb'
}
],
show: ['name', 'age']
}
}
]
function init() {
data.map(res => {
if (res.code == 200) {
console.log(
res.data.list.map(item => {
return {
name: item.name,
age: item.age
}
})
)
}
})
}
init()
Does this answer your question?

Formatting JSON for Google Charts API

Using MongoDB / Node consider the following payload:
var myObj = {
"date" : "1-23-45",
"one" : [
{
"a" : 8
},
{
"b" : 1
},
{
"c" : 9
},
{
"d" : 10
},
{
"e" : 12424
},
{
"f" : 11
},
{
"g" : 7
}
],
"two" : [
{
"h" : 6
},
{
"i" : 10
}
]
},
{
"date" : "1-24-45",
"one" : [
{
"a" : 8
},
{
"b" : 1
},
{
"c" : 9
},
{
"d" : 10
},
{
"e" : 12424
},
{
"f" : 11
},
{
"g" : 7
}
],
"two" : [
{
"h" : 6
},
{
"i" : 10
}
]
}
I am using Google Charts API and I would like to plot these points to a line graph. (see snippet)
<html>
<head>
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={
'modules':[{
'name':'visualization',
'version':'1',
'packages':['corechart']
}]
}"></script>
<script type="text/javascript">
google.setOnLoadCallback(drawChart);
var myObj = {
"cols": [{
"id": "",
"label": "year",
"type": "string"
}, {
"id": "",
"label": "sales",
"type": "number"
}, {
"id": "",
"label": "expenses",
"type": "number"
}],
"rows": [{
"c": [{
"v": "2001"
}, {
"v": 3
}, {
"v": 5
}]
}, {
"c": [{
"v": "2002"
}, {
"v": 5
}, {
"v": 10
}]
}, {
"c": [{
"v": "2003"
}, {
"v": 6
}, {
"v": 4
}]
}, {
"c": [{
"v": "2004"
}, {
"v": 8
}, {
"v": 32
}]
}, {
"c": [{
"v": "2005"
}, {
"v": 3
}, {
"v": 56
}]
}]
}
function drawChart() {
var data = new google.visualization.DataTable(myObj);
var options = {
title: 'My Chart',
curveType: 'function',
legend: {
position: 'right'
}
};
var chart = new google.visualization.LineChart(document.getElementById('curve_chart'));
chart.draw(data, options);
}
</script>
</head>
<body>
<div id="curve_chart" style="width: 100%; height: 500px"></div>
</body>
</html>
Using the JSON I am provided, what would be the most effective way to massage the data into the format accepted by Google Charts API? I have looked into D3 but it seemed to have a higher learning curve, would that be the most recommended route? Would it be better to query the dataset differently / aggregate the result?
Help is much appreciated, as this has been a 2 day long venture!
Update --
TL;DR
I need a script that goes from Format #1 => Format #2, no matter how big the payload is.
Format #1 - myObj
Format #2 -
var myObj = {
"cols": [{
"label": "Date",
"type": "string"
}, {
"label": "a",
"type": "number"
}, {
"label": "b",
"type": "number"
}, {
"label": "c",
"type": "number"
}, {
"label": "d",
"type": "number"
}, {
"label": "e",
"type": "number"
}, {
"label": "f",
"type": "number"
}, {
"label": "g",
"type": "number"
}, {
"label": "h",
"type": "number"
}, {
"label": "i",
"type": "number"
}
],
"rows": [{
"c": [{
"v": "day1"
}, {
"v": 300
}, {
"v": -500
}, {
"v": 23
}, {
"v": 120
}, {
"v": 150
}, {
"v": 1210
}, {
"v": 160
}, {
"v": 180
}, {
"v": 190
}]
}, {
"c": [{
"v": "day2"
}, {
"v": 1300
}, {
"v": -5200
}, {
"v": 253
}, {
"v": 6120
}, {
"v": 1350
}, {
"v": 110
}, {
"v": 2160
}, {
"v": 1180
}, {
"v": 1190
}]
}
]
}
Looking at your data and how it needs to be formatted, something like the below would work. You will need to loop over each object to get the cols and then map over each array to get the rows.
var dataObj = {
"cols": [],
"rows": []
};
for(property in myObj) {
if(typeof myObj[property] === 'string') {
dataObj.cols.push({
"label": property,
"type": "string"
});
} else {
dataObj.rows.push({
"c": []
});
dataObj.rows[dataObj.rows.length - 1]["c"].push({
"date": "day" + dataObj.rows.length // The day: 1, 2, 3, etc.
});
myObj[property].map(function(object) {
for(prop in object) {
dataObj.cols.push({
"label": prop,
"type": "number"
});
dataObj.rows[dataObj.rows.length - 1]["c"].push({
"v": object[prop]
});
}
});
}
}
JSFiddle with Google Chart example (Open Console to see formatted data)

mongodb getting the oldest of animals map/reduce

I've never tried map/reduce.
How would I get the oldest of each type of animal?
My data is like this:
[
{
"cateory": "animal",
"type": "cat",
"age": 4,
"id": "a"
},
{
"cateory": "animal",
"type": "bird",
"age": 3,
"id": "b"
},
{
"cateory": "animal",
"type": "cat",
"age": 7
"id": "c"
},
{
"cateory": "animal",
"type": "bird",
"age": 4,
"id": "d"
},
{
"cateory": "animal",
"type": "cat",
"age": 8,
"id": "e"
},
{
"cateory": "company",
"type": "Internet",
"age": 5,
"id": "Facebook"
}
]
I'm using node-mongodb-native. Thanks!
Your map function should look something like this:
map = function() {
emit({type: this.type}, {age: this.age});
}
And the reduce function:
reduce = function(key, values) {
maxAge = 0;
values.forEach(function(v) {
if (maxAge < v['age']) {
maxAge = v['age'];
}
});
return {age: maxAge};
}
It's pretty simple:
collection.find({type : 'animal'}).sort({animal: -1}).limit(1);

Categories