couchDb map/reduce min&max + other data - couchdb

I have a document list that consists of:
time
sessionId
appv
museum
I would like to use the couchDB map/reduce function to get the result:
key : sessionId, value : {begin : time, end: time, appv : appv, museum : museum}
for the begin value: the minimum time value.
for the end value: the maximum time value
Currently I can have the minimum and maximum value with this code:
MAP :
function(doc) {
if(doc.sessionId) {
emit(doc.sessionId, [doc.time])
}
}
REDUCE :
function(keys, values, rereduce) {
if (rereduce) {
return {
'min': values.reduce(function(a, b) { return Math.min(a, b.min) }, Infinity),
'max': values.reduce(function(a, b) { return Math.max(a, b.max) }, -Infinity),
}
} else {
return {
'min': Math.min.apply(null, values),
'max': Math.max.apply(null, values),
}
}
}
RESULT :
{"rows":[
{"key":"fromDev1548326238156","value":{"min":2,"max":999}}
]}
And when I use this map function:
function(doc) {
if(doc.sessionId) {
emit(doc.sessionId, [doc.time, doc.museum, doc.appv])
}
}
I can't find the reduce function that allows me to get the result I want
Can you help me?

Related

How to count a field if value is not null in elasticsearch

I have indexed some documents in ElasticSearch.
Short view looks like this:
{
"tenant_id":"abcd1234"
"provider_id":"3456"
.
.
.
"doctor_summary": ["line1", "line2", "line3"] OR it could be null.
}
I want to calculate this list as 1 if not null,
query_template = {
"bool":{
"must":[
{"term":{"tenant_id.keyword":tenant_id}},
{"term":{"provider_id.keyword":provider_id}},
{"range":{"visit_date":{"gte":from_date,"lte":to_date}}},
],
"filter":[]
}
}
aggs_query = {
"doctor_summary_count":{
"value_count":{"field":"doctor_summary.keyword"}
}
}
res = CLIENT.search(index = config['elasticsearch']['abcd'],
query = query_template,
size = 10000,
aggs = aggs_query)
After calling this aggregation query, it gives result as ( size of the list * total doctor_summary field).
For example: the result of above query on above document should be 1. (As it is not null).
But it gives as 3(because list contains 3 lines.)
You can use exist query in aggregation with filter aggregation.
Query:
{
"aggs": {
"count": {
"filter": {
"exists": {
"field": "doctor_summary.keyword"
}
}
}
}
}
Response:
"aggregations" : {
"count" : {
"doc_count" : 1
}
}

How can to implement recursion for loopback self relations?

I have a self relation in my model. How to implement recursion for parent-child hierarchy using self-join in loopback upto N-level?
The code given below will give us recursion only upto certain level but i want to implement it for N-LEVELS?
Menu.nest = function(callback) {
Menu.find({
"include":{
"relation":"menus",
"scope":{
"include":{
"relation":"menus"
}
}
}
}, function(err, results) {
if(err) return callback(err);
callback(err, results);
});
}
This is returning upto the limited number of levels
I want to implement recursion to implement upto N levels for this. Thanks
Your maximum depth of query & data is set in datasources.json see docs for details, so you'll want that to be your maximum N
{
"db": {
"name": "db",
"connector": "memory",
"maxDepthOfQuery": 5,
"maxDepthOfData": 16
}
}
I'm not able to test this right now, but this looks like a working/almost working snippet
const o = {};
const assignFunc = (o) => {
while(o.include) {
o = o.include.scope;
}
o.include = {
relation: "menus",
scope:{}
};
return o;
}
function rec(o, n) {
if (n == 0) {
return o;
}
assignFunc(o);
return rec(o, n - 1);
};
console.log(rec({}, 10));

How can I insert Infinity field values into MongoDB using Mongoose [duplicate]

I have JavaScript Object say:
var a = {b: Infinity, c: 10};
When I do
var b = JSON.stringify(a);
it returns the following
b = "{"b":null, "c":10}";
How is the JSON.stringify converts the object to strings?
I tried MDN Solution.
function censor(key, value) {
if (value == Infinity) {
return "Infinity";
}
return value;
}
var b = JSON.stringify(a, censor);
But in this case I have to return the string "Infinity" not Infinity. If I return Infinity it again converts Infinity to null.
How do I solve this problem.
Like the other answers stated, Infinity is not part of the values JSON can store as value.
You can reverse the censor method on parsing the JSON:
var c = JSON.parse(b, function (key, value) {
return value === "Infinity" ? Infinity : value;
});
JSON doesn't have Infinity or NaN, see this question:
JSON left out Infinity and NaN; JSON status in ECMAScript?
Hence { b: Infinity, c: 10 } isn't valid JSON. If you need to encode infinity in JSON, you probably have to resort to objects:
{
"b": { "is_infinity": true, "value": null },
"c": { "is_infinity": false, "value": 10 }
}
This structure is generated by, given your above example does what you say it does,
function censor(key, value) {
if (value == Infinity) {
return JSON.stringify ( { is_infinity: true, value: null } );
} else {
return JSON.stringify ( { is_infinity: false, value: value } );
}
}
var b = JSON.stringify(a, censor);
JSON doesn't support infinity/Nan.
Please refer the below links.
http://www.markhansen.co.nz/inspecting-with-json-stringify/
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/JSON/stringify
JSON left out Infinity and NaN; JSON status in ECMAScript?
Thanks,
Siva

In couchdb How to get sorting on value with reduce _count

"myview": {
"map": "function(doc) { if (doc.type == 'user') emit(doc.city,null)}",
"reduce": "_count"
},
It return city with count in value. Using group=true
How to sort this data base on highest value? Want to get most popular city first...
You can use list to sort your resultset. Following function can sort anytype of a resultset on value.
"sort": "function() {
var row;
var rows=[];
while(row = getRow())
{
rows.push(row)
}
rows.sort(function(a, b)
{
return a.value - b.value;
});
rows.reverse();
send(JSON.stringify({\"rows\" : rows}))
}"

How to use a variable for mapReduce in MongoDB with NodeJS

I have a collection of events that look like
{
_id: BSONID
name: "event_name",
values: {a: 10, b: 1000, c: 50}
}
I'm trying to use mapReduce them using
map = function() {
return emit([this.name, this.values['a']], this.values['b']);
}
reduce = function(key, values) {
// stuff
}
collection.mapReduce(map, reduce, { out: { inline: 1 } }, callback);
However, I would like to be able to dynamically change which values I map against. In essence, I'd like to have
var key = 'a';
var value = 'b';
map = function ()
{
return emit([this.name, this.values[key]], this.values[value]);
}
The problem is that the execution context isn't passed to mongodb. Any solution that doesn't rely on using string for functions?
Yes, you can pass a "scope" variable to MapReduce:
scope = {key : "a", value : "b"};
collection.mapReduce(map, reduce, {scope : scope, out: { inline: 1 } }, callback);

Resources