You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@couchdb.apache.org by Andrew Koster <an...@samsung.com> on 2015/02/25 14:43:34 UTC
How to query a view from within another view?
Dear all,
I have a CouchDB database with the following type of documents, representing
events that happen:
{ person: 1
timestamp: 1
event: { type: enter
room: b }
}
and
{ person: 2
timestamp: 5
event: { type: leave
room: b }
}
Now the problem that I want to solve is the following: I want to know the
total amount of time that every other person spent in the same room as
person 1, at the end of the day when all persons have left all rooms. Note
that any person can enter and leave many rooms at many different times. I
honestly don't know whether MapReduce is the best paradigm for this, or if I
should just export my data and write a separate script to figure this stuff
out (although this is probably not a feasible solution for our production
environment).
As a starting solution lets assume that all the data is sane, and thus
someone entering a room will also leave that room at a later time. However,
in a final solution this requirement will probably have to be relaxed,
because some events may be missing.
I have thought of a potential solution, but I have no idea whether this is
at all possible or how to do this in couchdb. Here is an outline.
1. Create a view that emits the following format, for every person
entering a room event:
{ [room, person, timestamp], null }
2. Create a view that emits { [room, timestamp], null} for every time
person 1 exits the room (could be for all people, but is unnecessary).
3. Create a view that for each exiting a room event for any person except
person 1, does the following. In the mapping step:
. Queries the first view to find the last timestamp when that person
entered the room.
. Queries the first view to find all times before the exiting the
room event that person 1 entered that room
. For each of those times, queries the second view to find all exit
times for that room, and for each interval checks what the overlap is.
. Sum these overlaps together and emit as { person, time }
Reduce: for every person, sum all the times together.
However, this relies on me being able to figure out how to query a different
view from within a view. Does anybody know if that is possible, and if so,
how?
Kind regards,
Andrew Koster
RE: How to query a view from within another view?
Posted by Andrew Koster <an...@samsung.com>.
Kiril,
Thanks for your answer. If I understand list functions correctly they can
transform a view, which will allow me to hone in on the information I need
within one of my views, but I will still need 3 different views and some
external processing to put together all the information that I need? Or do
you mean that I can use the list function to load the results into memory
and perform all my computation within the list function, simply iterating
over my documents various times. Something like:
{ "_id": "_design/roomsharetimes",
"lists": {
"gettimes": "function(head, req) {
var allEvents = []
while(row = getRow()) {
allEvents[allEvents.length] = row;
}
result = doAllMyProcessing(allEvents);
asHTML(result);
}"
}
"views": {
"enterleaveevents": {
"map": "function(doc) {
if (doc.event && (doc.event.type == "enter" || doc.event.type ==
"leave"))
{ emit([doc.event, doc.room, doc.person, doc.timestamp], null); }
}"
}
}
}
This *should* work (haven't tried it yet), but I am doing the bulk of the
work outside the actual view.
Cheers,
Andrew
-----Original Message-----
From: Kiril Stankov [mailto:kiril@open-net.biz]
Sent: 25 February 2015 18:49
To: user@couchdb.apache.org
Subject: Re: How to query a view from within another view?
Andrew,
it is not possible to query a view from another view.
However, there is a List function, which you can feed with params from the
query.
So, if you have some results from the first view, you can then another view
with a List function that gets some input.
Have a look here:
<http://guide.couchdb.org/draft/transforming.html>
http://guide.couchdb.org/draft/transforming.html
------------------------------------------------------------------------
*With best regards,*
Kiril Stankov
On 25-Feb-15 3:43 PM, Andrew Koster wrote:
> Dear all,
>
> I have a CouchDB database with the following type of documents,
> representing events that happen:
>
> { person: 1
>
> timestamp: 1
>
> event: { type: enter
>
> room: b }
>
> }
>
> and
>
> { person: 2
>
> timestamp: 5
>
> event: { type: leave
>
> room: b }
>
> }
>
> Now the problem that I want to solve is the following: I want to know
> the total amount of time that every other person spent in the same
> room as person 1, at the end of the day when all persons have left all
> rooms. Note that any person can enter and leave many rooms at many
> different times. I honestly don't know whether MapReduce is the best
> paradigm for this, or if I should just export my data and write a
> separate script to figure this stuff out (although this is probably
> not a feasible solution for our production environment).
>
> As a starting solution lets assume that all the data is sane, and thus
> someone entering a room will also leave that room at a later time.
> However, in a final solution this requirement will probably have to be
> relaxed, because some events may be missing.
>
> I have thought of a potential solution, but I have no idea whether
> this is at all possible or how to do this in couchdb. Here is an outline.
>
> 1. Create a view that emits the following format, for every person
> entering a room event:
>
> { [room, person, timestamp], null }
>
> 2. Create a view that emits { [room, timestamp], null} for every time
> person 1 exits the room (could be for all people, but is unnecessary).
>
> 3. Create a view that for each exiting a room event for any person
except
> person 1, does the following. In the mapping step:
>
> . Queries the first view to find the last timestamp when that
person
> entered the room.
>
> . Queries the first view to find all times before the exiting the
> room event that person 1 entered that room
>
> . For each of those times, queries the second view to find all
exit
> times for that room, and for each interval checks what the overlap is.
>
> . Sum these overlaps together and emit as { person, time }
>
> Reduce: for every person, sum all the times together.
>
> However, this relies on me being able to figure out how to query a
> different view from within a view. Does anybody know if that is
> possible, and if so, how?
>
> Kind regards,
>
> Andrew Koster
>
>
>
>
Re: How to query a view from within another view?
Posted by Kiril Stankov <ki...@open-net.biz>.
Andrew,
it is not possible to query a view from another view.
However, there is a List function, which you can feed with params from
the query.
So, if you have some results from the first view, you can then another
view with a List function that gets some input.
Have a look here:
http://guide.couchdb.org/draft/transforming.html
------------------------------------------------------------------------
*With best regards,*
Kiril Stankov
On 25-Feb-15 3:43 PM, Andrew Koster wrote:
> Dear all,
>
> I have a CouchDB database with the following type of documents, representing
> events that happen:
>
> { person: 1
>
> timestamp: 1
>
> event: { type: enter
>
> room: b }
>
> }
>
> and
>
> { person: 2
>
> timestamp: 5
>
> event: { type: leave
>
> room: b }
>
> }
>
> Now the problem that I want to solve is the following: I want to know the
> total amount of time that every other person spent in the same room as
> person 1, at the end of the day when all persons have left all rooms. Note
> that any person can enter and leave many rooms at many different times. I
> honestly don't know whether MapReduce is the best paradigm for this, or if I
> should just export my data and write a separate script to figure this stuff
> out (although this is probably not a feasible solution for our production
> environment).
>
> As a starting solution lets assume that all the data is sane, and thus
> someone entering a room will also leave that room at a later time. However,
> in a final solution this requirement will probably have to be relaxed,
> because some events may be missing.
>
> I have thought of a potential solution, but I have no idea whether this is
> at all possible or how to do this in couchdb. Here is an outline.
>
> 1. Create a view that emits the following format, for every person
> entering a room event:
>
> { [room, person, timestamp], null }
>
> 2. Create a view that emits { [room, timestamp], null} for every time
> person 1 exits the room (could be for all people, but is unnecessary).
>
> 3. Create a view that for each exiting a room event for any person except
> person 1, does the following. In the mapping step:
>
> . Queries the first view to find the last timestamp when that person
> entered the room.
>
> . Queries the first view to find all times before the exiting the
> room event that person 1 entered that room
>
> . For each of those times, queries the second view to find all exit
> times for that room, and for each interval checks what the overlap is.
>
> . Sum these overlaps together and emit as { person, time }
>
> Reduce: for every person, sum all the times together.
>
> However, this relies on me being able to figure out how to query a different
> view from within a view. Does anybody know if that is possible, and if so,
> how?
>
> Kind regards,
>
> Andrew Koster
>
>
>
>