How to Use Go With MongoDB For Group? - go

data
userId height
curry 1
curry 2
kd 3
kd 4
james 2
input: userIds=[curry,kd,james]
i want
curry 2
kd 4
james 2
So, i want one record with the highest height in each group.

Get!!!!
but I don't understand.
$sort must definition before $group ,
if not, the height is not the largest.
Why? Or i was wrong ?
users := []string{"curry", "kd", "james"}
pipe := mongo.Pipeline{
{
{Key: "$match", Value: bson.D{{Key: "userId", Value: bson.M{"$in": users}}}},
},
{
// must before $group
{Key: "$sort", Value: bson.D{{Key: "height", Value: -1}}},
},
{
{Key: "$group",
Value: bson.D{
{Key: "_id", Value: "$userId"},
{Key: "height", Value: bson.D{{Key: "$first", Value: "$height"}}},
},
},
},
//don't work !!!!!.the height is not the largest
//{
// {Key: "$sort", Value: bson.D{{Key: "height", Value: -1}}},
//},
}

Related

How to create a bitwise OR hash map key?

Given a hash map keyed by unique key M that contains objects with unique ids N (numeric for simplicity):
{
// [key: M]: [{ id: N }],
a3b84ea: [{ id: 10129 }, { id: 32241 }],
f4b00dd: [{ id: 57909 }, { id: 82033 }],
b9982ca: [{ id: 20348 }, { id: 97412 }],
}
I would like to be able to efficiently look up a value by ANY of the ids N.
e.g.
get(10129) → [{ id: 10129 }, { id: 32241 }]
get(32241) → [{ id: 10129 }, { id: 32241 }]
get(57909) → [{ id: 57909 }, { id: 82033 }]
...
I'm pretty sure that a O(1) bitwise OR hashing function is not possible, as there is no way to get the compound hash of, for example, 10129 and 32241 when you only have 10129.
However, is there a data structure that would allow O(2) lookup with any of the ids N? i.e. a 2-step lookup without having to iterate through all keys M?

AmCharts serial multiple data sets

Taking a look at different examples on the documentation, I found that the only way to include multiple graphs (or lines) on a serial chart would be to do so by placing the data in one array as such:
[{
category: 1,
value1: .8,
value2: .64,
},
{
category: 2,
value1: .75,
value2: -.4,
}];
However, this is rather tedious if you have multiple data sets you are trying to display at once; is there an alternative way to do this, where you would pass multiple arrays at once (this is what I figured an implementation would look like, but it is not the case):
[
// First set of data
{ category: 0, value: .5},
{ category: 1, value: .5},
{ category: 2, value: .5},
{ category: 3, value: .5},
{ category: 4, value: .3},
{ category: 5, value: 1}
],
// Second set of data
[
{ category: 0, value: .5 },
{ category: 1, value: .3 },
{ category: 2, value: .25 },
{ category: 3, value: .6 },
{ category: 4, value: .79 },
{ category: 5, value: .81 }
]],
Any ideas on how this may be done? Or would I need to do switch to a different type of chart?
This isn't possible in the regular AmCharts JavaScript Charts library. The only supported format is a single array of objects with the values consolidated by category as you've noticed. You'll have to preprocess your data beforehand.
The AmCharts Stock Chart library supports separate arrays of data in the dataSets array, however it only supports date-based data.
AmCharts.makeChart("chartdiv", {
"type": "stock",
"dataSets": [{
// other properties omitted
"dataProvider": [{
category: "2017-08-01,
value: 3
}, {
category: "2017-08-02,
value: 2
}, {
category: "2017-08-03,
value: 1
}, // ...
]
}, {
// other properties omitted
"dataProvider": [{
category: "2017-08-01,
value: 10
}, {
category: "2017-08-02,
value: 9
}, {
category: "2017-08-03,
value: 5
}, // ...
]
},
// ...
]
// ...
});
You can see this in action in the any of the stock chart demos.

Generate an array of charts

I want to generate an array of charts and insert them into the DOM.
(I want to use these charts as templates and insert them at the right time)
like that:
Var array = [];
array[0].kendoChart ({// .........});
array[1].kendoChart ({// .........});
array.forEach (function (el) {
$('body').append(el);
})
Tell me how to be?
I would keep an array of the data used to generate the charts, and then generate them at the time of insert.
In HTML provide a container for the charts to be inserted (could be body as in your example):
<div id="chartsContainer" ></div>
Then in script have an array of the data needed to generate the multiple charts, e.g. :
var charts = [
{
chartid: "id1", title: "Chart 1",
data: [{ x: "item1", y: 2}, { x: "item2", y: 4},{ x: "item3", y: 1}]
},
{
chartid: "id2", title: "Chart 2",
data: [{ x: "item1", y: 8}, { x: "item2", y: 3},{ x: "item3", y: 7},{ x: "item4", y: 2}]
},
{
chartid: "id3", title: "Chart 3",
data: [{ x: "item1", y: 1}, { x: "item2", y: 2},{ x: "item3", y: 4} ]
},
];
Finally loop through the array, insert DIVs in the container and create a chart in each DIV:
$("#chartsContainer").empty();
var arrayLength = charts.length;
for (var i = 0; i < arrayLength; i++) {
var div = $('<div id="' + charts[i].chartid + '"></div>');
$("#chartsContainer").append(div);
div.kendoChart({
theme: "Flat",
chartArea: { height: 200 },
dataSource: {data: charts[i].data },
title: { text: charts[i].title},
seriesDefaults: {type: "column"},
series: [{field: "y" }],
categoryAxis: {
field: "x",
majorGridLines: {visible: false },
}
});
}
Working DEMO

Lodash filter unique documents

How can I filter the current data:
[{
key: 'T1',
legs:[{ fno: 'W321',date: '2017-01-02 18:20:00.000+0200'}],
fare: { type: 'B', price: 25 }
},{
key: 'T1',
legs:[{ fno: 'W321', date: '2017-01-02T18:20:00.000+0200'}],
fare: { type: 'E', price: 23 }
},{
key: 'T1',
legs:[{ fno: 'W321', date: '2017-01-02T18:20:00.000+0200'}],
fare: { type: 'E', price: 20}
}]
I want to group by legs[0].fno, legs[0].date and fare.type, and keep the lowest priced items in each group. This is the expected result:
[{
key: 'T1',
legs:[{ fno: 'W321',date: '2017-01-02T18:20:00.000+0200'}],
fare: { type: 'B', price: 25}
},{
key: 'T1',
legs:[{ fno: 'W321',date: '2017-01-02T18:20:00.000+0200'}],
fare: { type: 'E', price: 20}
}]
Use _.groupBy() with a callback to create a string to group by, then _.map() each group to a single item using _.minBy():
var data = [{"key":"T1","legs":[{"fno":"W321","date":"2017-01-02 18:20:00.000+0200"}],"fare":{"type":"B","price":25}},{"key":"T1","legs":[{"fno":"W321","date":"2017-01-02T18:20:00.000+0200"}],"fare":{"type":"E","price":23}},{"key":"T1","legs":[{"fno":"W321","date":"2017-01-02T18:20:00.000+0200"}],"fare":{"type":"E","price":20}}];
var result = _(data)
// group by the combined group keys
.groupBy(function(o) {
// extract all group keys and join them to a string
return _.at(o, ['key', 'legs[0].date', 'fare.type']).join('');
})
.map(function(group) {
// get the object object with the minimum fare.price
return _.minBy(group, 'fare.price');
})
.value();
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Rethink db order by optional field

Docs:
[{
id: 111,
weight: 1
},{
id: 222,
},{
id: 333,
weight: -1
}]
I want to order the docs by weight if weight not exists treat its weight as 0
How can I do that ?
You can use function as mentioned here with default:
r.table(TABLE_NAME).orderBy(r.asc(function(doc) {
return doc("weight").default(0)
}));

Resources