1

I've got race participant data in some documents, organized by race stage, runner position, and the time the runner passed through the stage.

I need to find a particular bib (?key=357) and grab the last time it went through a stage (doc.bib_data[i].time), which stage it was (id) and the position (i).

If I specify a particular bib_data array index, I get results, but if I loop through the bib_data, I don't get any results, even if I don't filter for anything.

VIEW with a specific index, to show what the document data looks like:

function (doc, meta) {
  emit(doc.bib_data[2].bib,doc.bib_data[2].time);
}

RESULT:

{
 "id": "007",
 "key": "357",
 "value": "1910:38",
 "doc": {
  "_id": "007",
  "_rev": "4-bdce057c8ad2ce975b9ffca9eb9dfd82",
  "ew_ham": "KM6WKA",
  "stage_ew_ham": "KK6DA",
  "bib_data": {
   "1": {
    "bib": "45",
    "time": "1910:35"
   },
   "2": {
    "bib": "357",
    "time": "1910:38"
   },
   "3": {
    "bib": "22",
    "time": "1910:40"
   }
  }
 }
}

How do I get results ONLY for "bib:357"?

I need to collect the stage, the position and the time, i.e. ["007","2","1910:38"]

   "2": {
    "bib": "357",
    "time": "1910:38"
   },

Here's my current QUERY:

http://[IP_ADDR]:5984/[DB_NAME]/_design/[DESIGN_DOC]/_view/[VIEW_NAME]?key=123

And my VIEW that attempts to loop through bib_data:

function (doc, meta) {
  for(i=0;i<doc.bib_data.length;i++) {
    if(doc.bib_data[i].bib) {
      emit( i, doc.bib_data[i].bib, doc.bib_data[i].time );
    }
  }
}

Which returns no results.

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
James Butler
  • 43
  • 1
  • 5

1 Answers1

1

The view code

function(doc, meta) {
  for (i = 0; i < doc.bib_data.length; i++) {
    if (doc.bib_data[i].bib) {
      emit(i, doc.bib_data[i].bib, doc.bib_data[i].time);
    }
  }
}

Is totally incorrect as it is an attempt to index iterate bib_data as if it were an array but it's an object. So fix that first [1]:

function (doc) {
  for (var key in doc.bib_data) {
    if (doc.bib_data.hasOwnProperty(key)) {
      var item = doc.bib_data[key];
      /* do something with the bib item. */
    }
  }
}

Now it's time to emit the data of interest. It's not super clear what is desired from your post, but here's a start, noting I am emitting what appear to be numbers as numbers not strings:

function (doc) {
  for (var key in doc.bib_data) {
    if (doc.bib_data.hasOwnProperty(key)) {
      var item = doc.bib_data[key];
      if(item.bib) {
        emit([parseInt(item.bib), parseInt(key), item.time]);
      }
    }
  }
}

Given the doc you posted as the only doc in the database with design doc and view name as bib using cURL:

curl -G <url to db>/_design/bib/_view/bib

will return

{ "total_rows":3,"offset":0,"rows":[
  {"id": "007", "key": [22,3,"1910:40"], "value": null},
  {"id": "007", "key": [45,1,"1910:35"], "value": null},
  {"id": "007", "key": [357,2,"1910:38"], "value": null}
]}

Because the bib view is generating a complex key one must query[2] using start_key and end_key. So to get view documents with a bib of 357

 curl -G <url to db>/_design/bib/_view/bib -d "start_key=[357]" -d "end_key=[357,{}]"

will return

{"total_rows":3,"offset":2,"rows":[
{"id":"007","key":[357,2,"1910:38"],"value":null}
]}

I am not seeing much utility with incorporating the index/key - maybe you want this instead?

emit([parseInt(item.bib), item.time], parseInt(key));


1 Iterate through object properties
2 /{db}/_design/{ddoc}/_view/{view}
RamblinRose
  • 4,883
  • 2
  • 21
  • 33
  • 1
    Thank you, RamblinRose! You really cleared it up, for me. – James Butler Apr 19 '20 at 17:30
  • To expand on my comment: You cleared it up for me in that I'm working with an object, rather than an array, and in helping me to understand the couchdb syntax for getting at what I needed. I'm a bit of an idiot for not seeing the object notation ... In re: index/key: That's the Stage indicator. So ... 09m = 1 mile out from the Stage, 09k = 200 meters out and 009 = the Stage marker. I want to pull the most-recent entry in the doc to be able to see where the runner was last recorded. Thanks, again. – James Butler Apr 20 '20 at 01:41