I have below response from my map reduce .
Now i want to count the number of rows in the response can any one help me how i can do it in cloudant? I need something in response like to get the total count of distinct correlationid in a period.
{
rows: [
{
key: [
"201705",
"aws-60826346-"
],
value: null
},
{
key: [
"201705",
"aws-60826348802-"
],
value: null
},
{
key: [
"201705",
"aws-las97628elb"
],
value: null
},
{
key: [
"201705",
"aws-ve-test"
],
value: null
},
{
key: [
"201705",
"aws-6032dcbce"
],
value: null
},
{
key: [
"201705",
"aws-60826348831d"
],
value: null
},
{
key: [
"201705",
"aws-608263488833926e"
],
value: null
},
{
key: [
"201705",
"aws-608263488a74f"
],
value: null
}
]
}
You need to implement a slightly obscure concept called "chained map-reduce" to accomplish this. You can't do this in the Cloudant administrative GUI, so you'll have to write your design document by hand.
Have your map/reduce emit an array as the key. The 1st array element will be month
and the second will be your correlationid
. The value should be 1. Then specify the built-in _count
as the reduce function.
Now you need to add the chaining part. Chaining basically involves automatically copying the result of a map/reduce into a new database. You can then do another map/reduce on that database. Thereby creating a chain of map/reduces...
Here's a tiny sample database using your example:
https://rajsingh.cloudant.com/so44106569/_all_docs?include_docs=true&limit=200
Here's the design document containing the map/reduce, along with the dbcopy
command that updates a new database (in this case called sob44106569
) with the results of the view called view
:
{
"_id": "_design/ddoc",
"_rev": "11-88ff7d977dfff81a05c50b13d854a78f",
"options": {
"epi": {
"dbcopy":
{
"view": "sob44106569"
}
}
},
"language": "javascript",
"views": {
"view": {
"reduce": "_count",
"map": "function (doc) {\n emit([doc.month, doc.machine], 1);\n}"
}
}
}
Here's the result of the map function (no reduce) showing 10 rows. Notice that there are two documents with month 201705
and machine aws-6032dcbce
:
https://rajsingh.cloudant.com/so44106569/_design/ddoc/_view/view?limit=200&reduce=false
If you just do the built-in _count
reduce on this view at group_level=1
, you'll get a value of 9 for 201705, which is wrong for your purposes because you want to count that aws-6032dcbce
only once, even though it shows up in the data twice:
https://rajsingh.cloudant.com/so44106569/_design/ddoc/_view/view?limit=200&reduce=true&group=true&group_level=1
So let's take a quick look at the map/reduce at group_level=2
. This is what gets copied to the new database:
https://rajsingh.cloudant.com/so44106569/_design/ddoc/_view/view?limit=200&reduce=true&group=true&group_level=2
Here you see that aws-6032dcbce
only shows up once (but with value=2), so this is a useful view. The dbcopy
part of our map/reduce creates the database sob44106569
based on this view. Let's look at that:
https://rajsingh.cloudant.com/sob44106569/_all_docs?include_docs=true
Now we can run a very simple map/reduce on that database, emitting the month and machine again (now they are in an array so have different names), but this time the repeated values for machine have already been "reduced" away.
function (doc) {
if (doc.key && doc.key.length == 2 )
emit(doc.key[0], doc.key[1]);
}
And finally here's the count of distinct "machines". Now we can finally see the desired value of 8 for 201705.
https://rajsingh.cloudant.com/sob44106569/_design/views/_view/counted?limit=200&reduce=true&group=true&group_level=1
response:
{
"rows": [
{
"key": "201705",
"value": 8
},
{
"key": "201706",
"value": 1
}
]
}
Emit 1 instead of null and use the built-in reducer _count.