Reputation: 43
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.
Upvotes: 1
Views: 74
Reputation: 4963
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));
Upvotes: 1