You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@couchdb.apache.org by Manuel Padrón Marrtínez <ma...@banot.net> on 2009/03/04 12:19:38 UTC

Filtering a cloud of points

Hi :

I have a problem with views (again). I have a cloud of points in a 2d space, I mean each point has X 
and Y position, and each point is in a document:

{
  "Point":
      {
        "X":20,
        "Y":30
      }
}

I need to make a view to filter a region of space, I mean all the points between X0-X1 and Y0-Y1.
I've tried to make a view like this:

MAP:
function(doc) {
  emit([[doc.X],[doc.Y]], doc);
}

And tried to filter with start - end key (for example : startkey=[[1],[0]]&endkey=[[3],[5]]) but I 
get points that are out of region (like [[1][9]]).
I've also tried with objects, simple vectos ([X,Y]) and still the same results.

Anyone knows how to solve it? There any way ? Or should I make a view for X coordinate, another for Y 
coordinate and try to make a ""join"" in my program?

Thanks in advance

Manuel Padrón Martínez

Re: Filtering a cloud of points

Posted by Paul Davis <pa...@gmail.com>.
There's also GeoCouch:

http://vmx.cx/cgi-bin/blog/index.cgi/geocouch-geospatial-queries-with-couchdb:2008-10-26:en,CouchDB,Python,geo

Paul

On Wed, Mar 4, 2009 at 9:59 AM, kowsik <ko...@gmail.com> wrote:
> I was playing around with time slices and I see some similarities
> here. Here's kinda how my docs look:
>
> {
>    start: 123345,
>    ...
> }
>
> where start is in seconds (say). It's now possible to do this (call
> this view 'time/slice'):
>
> map: function(d) {
>    emit('1m', Math.floor(d.start/60));
>    emit('5m', Math.floor(d.start/60/5));
>    emit('10m', Math.floor(d.start/60/10));
>    emit('1h', Math.floor(d.start/60/60));
> }
>
> reduce: function(k, v) {
>    return sum(v);
> }
>
> What this does is essentially chunk up the time into 1-dimensional
> segments (of different granularity). This allows the application to
> query time slices very easily like so:
>
> _view/time/slice?startkey=['1h']&endkey=['1h',{}]&group=true
>
> This gives me high level 1hr regions and a count of all documents that
> fall into each hour. If you now want to "zoom in", here's what you do:
>
> _view/time/slice?startkey=["1m",5]&endkey=["1m",10]&group=true
>
> This returns all documents that fall within the 5 - 10 minute segment.
> I'm sure you can partition the 2D space in similar ways using numbered
> cells chunked up by some quantity. So your map might look like this:
>
> map: function(d) {
>    emit(['10x10xy', Math.floor(d.x/10), Math.floor(d.y/10)], 1);
>    emit(['10x10yx', Math.floor(d.y/10), Math.floor(d.x/10)], 1);
> }
>
> So if you want to find out the count of documents in y-axis 50 between
> x-axis 10 to 20, you could do this:
>
> _view/cell/slice?startkey=["10x10yx", 5, 1]&endkey=["10x10yz", 5, 2]&group=true
>
> Hope that helps,
>
> K.
>
> On Wed, Mar 4, 2009 at 6:36 AM, Jason Davies <ja...@jasondavies.com> wrote:
>> Hi Manuel,
>>
>> On 4 Mar 2009, at 11:19, Manuel UGFkcsOzbiBNYXLhcnTDrW5leg== wrote:
>>
>>> And tried to filter with start - end key (for example :
>>> startkey=[[1],[0]]&endkey=[[3],[5]]) but I
>>> get points that are out of region (like [[1][9]]).
>>> I've also tried with objects, simple vectos ([X,Y]) and still the same
>>> results.
>>>
>>> Anyone knows how to solve it? There any way ? Or should I make a view for
>>> X coordinate, another for Y
>>> coordinate and try to make a ""join"" in my program?
>>
>>
>> CouchDB's views produce a linear (one-dimensional) keyspace, so
>> multi-dimensional queries like this are currently not possible, unless, as
>> you say, you do two separate queries on the X-keyspace and the Y-keyspace
>> and then compute the intersection of the results in your client.
>>
>> There has been talk of supporting view intersections but at the moment this
>> is still being discussed/dreamed of :-)  Essentially this would allow us to
>> do a single query that performs two view queries on separate linear
>> keyspaces and then intersects them server-side.  The obvious advantage here
>> is that the discarded data doesn't needlessly get transferred across the
>> wire.
>>
>> --
>> Jason Davies
>>
>> www.jasondavies.com
>>
>

Re: Filtering a cloud of points

Posted by kowsik <ko...@gmail.com>.
I was playing around with time slices and I see some similarities
here. Here's kinda how my docs look:

{
    start: 123345,
    ...
}

where start is in seconds (say). It's now possible to do this (call
this view 'time/slice'):

map: function(d) {
    emit('1m', Math.floor(d.start/60));
    emit('5m', Math.floor(d.start/60/5));
    emit('10m', Math.floor(d.start/60/10));
    emit('1h', Math.floor(d.start/60/60));
}

reduce: function(k, v) {
    return sum(v);
}

What this does is essentially chunk up the time into 1-dimensional
segments (of different granularity). This allows the application to
query time slices very easily like so:

_view/time/slice?startkey=['1h']&endkey=['1h',{}]&group=true

This gives me high level 1hr regions and a count of all documents that
fall into each hour. If you now want to "zoom in", here's what you do:

_view/time/slice?startkey=["1m",5]&endkey=["1m",10]&group=true

This returns all documents that fall within the 5 - 10 minute segment.
I'm sure you can partition the 2D space in similar ways using numbered
cells chunked up by some quantity. So your map might look like this:

map: function(d) {
    emit(['10x10xy', Math.floor(d.x/10), Math.floor(d.y/10)], 1);
    emit(['10x10yx', Math.floor(d.y/10), Math.floor(d.x/10)], 1);
}

So if you want to find out the count of documents in y-axis 50 between
x-axis 10 to 20, you could do this:

_view/cell/slice?startkey=["10x10yx", 5, 1]&endkey=["10x10yz", 5, 2]&group=true

Hope that helps,

K.

On Wed, Mar 4, 2009 at 6:36 AM, Jason Davies <ja...@jasondavies.com> wrote:
> Hi Manuel,
>
> On 4 Mar 2009, at 11:19, Manuel UGFkcsOzbiBNYXLhcnTDrW5leg== wrote:
>
>> And tried to filter with start - end key (for example :
>> startkey=[[1],[0]]&endkey=[[3],[5]]) but I
>> get points that are out of region (like [[1][9]]).
>> I've also tried with objects, simple vectos ([X,Y]) and still the same
>> results.
>>
>> Anyone knows how to solve it? There any way ? Or should I make a view for
>> X coordinate, another for Y
>> coordinate and try to make a ""join"" in my program?
>
>
> CouchDB's views produce a linear (one-dimensional) keyspace, so
> multi-dimensional queries like this are currently not possible, unless, as
> you say, you do two separate queries on the X-keyspace and the Y-keyspace
> and then compute the intersection of the results in your client.
>
> There has been talk of supporting view intersections but at the moment this
> is still being discussed/dreamed of :-)  Essentially this would allow us to
> do a single query that performs two view queries on separate linear
> keyspaces and then intersects them server-side.  The obvious advantage here
> is that the discarded data doesn't needlessly get transferred across the
> wire.
>
> --
> Jason Davies
>
> www.jasondavies.com
>

Re: [user] Re: Filtering a cloud of points

Posted by Wout Mertens <wm...@cisco.com>.
On Mar 4, 2009, at 3:36 PM, Jason Davies wrote:

> There has been talk of supporting view intersections but at the  
> moment this is still being discussed/dreamed of :-)  Essentially  
> this would allow us to do a single query that performs two view  
> queries on separate linear keyspaces and then intersects them server- 
> side.  The obvious advantage here is that the discarded data doesn't  
> needlessly get transferred across the wire.

How about writing an _external procedure to do the merging server  
side? At least then the data stays local.

http://wiki.apache.org/couchdb/ExternalProcesses

Wout.



Re: Filtering a cloud of points

Posted by Jason Davies <ja...@jasondavies.com>.
Hi Manuel,

On 4 Mar 2009, at 11:19, Manuel UGFkcsOzbiBNYXLhcnTDrW5leg== wrote:

> And tried to filter with start - end key (for example :  
> startkey=[[1],[0]]&endkey=[[3],[5]]) but I
> get points that are out of region (like [[1][9]]).
> I've also tried with objects, simple vectos ([X,Y]) and still the  
> same results.
>
> Anyone knows how to solve it? There any way ? Or should I make a  
> view for X coordinate, another for Y
> coordinate and try to make a ""join"" in my program?


CouchDB's views produce a linear (one-dimensional) keyspace, so multi- 
dimensional queries like this are currently not possible, unless, as  
you say, you do two separate queries on the X-keyspace and the Y- 
keyspace and then compute the intersection of the results in your  
client.

There has been talk of supporting view intersections but at the moment  
this is still being discussed/dreamed of :-)  Essentially this would  
allow us to do a single query that performs two view queries on  
separate linear keyspaces and then intersects them server-side.  The  
obvious advantage here is that the discarded data doesn't needlessly  
get transferred across the wire.

--
Jason Davies

www.jasondavies.com

Re: Filtering a cloud of points

Posted by Manuel Padrón Martínez <ma...@banot.net>.
> Not sure if this is the best, or a workable solution , I haven't tried
> it, but it may lead to one.  If you look at :
> http://wiki.apache.org/couchdb/View_collation?action=show&redirect=ViewCollation
>   It shows how views are collated at the bottom.

I've read it but it don't seems to solve the problem trying to filter by two "ranged properties" at 
the same time (like in the case) 

> The example you posted could be solved by doing 3 requests - all
> points in each row, and then combining them in your code:
> 
That doesn't work to me,because (in this case) X and Y are real numbers... I could make a petition to 
get the X between X0-X1 and then get the Y between Y0-Y1 and try to make the join in my code. But 
that is what I'm trying to avoid. I have read 
(http://www.eflorenzano.com/blog/post/why-couchdb-sucks/) and in the 7th comment talks about a merge 
function that is not implemented yet .I think  merge will do what I want (two maps one for X 
and one for Y and a merge that make a ""join""). Anyone knows the state of merge or if it will be 
implemented ?

> 
> Hope that helps,

Thanks 

> 
> danny
> 
> On Wed, Mar 4, 2009 at 6:19 AM, Manuel Padrón Marártínez
> <ma...@banot.net> wrote:
> > Hi :
> >
> > I have a problem with views (again). I have a cloud of points in a 2d space, I mean each point has X
> > and Y position, and each point is in a document:
> >
> > {
> >  "Point":
> >      {
> >        "X":20,
> >        "Y":30
> >      }
> > }
> >
> > I need to make a view to filter a region of space, I mean all the points between X0-X1 and Y0-Y1.
> > I've tried to make a view like this:
> >
> > MAP:
> > function(doc) {
> >  emit([[doc.X],[doc.Y]], doc);
> > }
> >
> > And tried to filter with start - end key (for example : startkey=[[1],[0]]&endkey=[[3],[5]]) but I
> > get points that are out of region (like [[1][9]]).
> > I've also tried with objects, simple vectos ([X,Y]) and still the same results.
> >
> > Anyone knows how to solve it? There any way ? Or should I make a view for X coordinate, another for Y
> > coordinate and try to make a ""join"" in my program?
> >
> > Thanks in advance
> >
> > Manuel Padrón Martínez
> >

Re: Filtering a cloud of points

Posted by Daniel Gagne <ga...@mit.edu>.
Not sure if this is the best, or a workable solution , I haven't tried
it, but it may lead to one.  If you look at :
http://wiki.apache.org/couchdb/View_collation?action=show&redirect=ViewCollation
  It shows how views are collated at the bottom.

The example you posted could be solved by doing 3 requests - all
points in each row, and then combining them in your code:

startkey=[[1],[0]]&endkey=[[1],[5]]
startkey=[[2],[0]]&endkey=[[2],[5]]
startkey=[[3],[0]]&endkey=[[3],[5]]

Hope that helps,

danny

On Wed, Mar 4, 2009 at 6:19 AM, Manuel Padrón Marártínez
<ma...@banot.net> wrote:
> Hi :
>
> I have a problem with views (again). I have a cloud of points in a 2d space, I mean each point has X
> and Y position, and each point is in a document:
>
> {
>  "Point":
>      {
>        "X":20,
>        "Y":30
>      }
> }
>
> I need to make a view to filter a region of space, I mean all the points between X0-X1 and Y0-Y1.
> I've tried to make a view like this:
>
> MAP:
> function(doc) {
>  emit([[doc.X],[doc.Y]], doc);
> }
>
> And tried to filter with start - end key (for example : startkey=[[1],[0]]&endkey=[[3],[5]]) but I
> get points that are out of region (like [[1][9]]).
> I've also tried with objects, simple vectos ([X,Y]) and still the same results.
>
> Anyone knows how to solve it? There any way ? Or should I make a view for X coordinate, another for Y
> coordinate and try to make a ""join"" in my program?
>
> Thanks in advance
>
> Manuel Padrón Martínez
>