count number of rows in cloudant in response

2019-06-10 10:40发布

问题:

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
}
]
}

回答1:

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
    }
  ]
}


回答2:

Emit 1 instead of null and use the built-in reducer _count.