views:

230

answers:

4

I'm having problem getting the right results in my coordinate system. To explain my system, I have this simple database that have x_axis, y_axis and name columns. I don't need to get all the data, I just need to display some part of it.

For example, I have a coordinate system that have 10:10(meaning from x_axis -10 to 10 and from y_axis -10 to 10) and I want to display only 49 coordinates. In sql query I can do it something like this: "select * from coordinate where x_axis >= -3 and x_axis <= 3 and y_axis >= -3 y_axis <= 3"

I tried this function but no success:

   "by_range": {
       "map": "function(doc) { emit([doc.x_axis, doc.y_axis], doc) }"
   }

by_range?startkey=[-3,-3]&endkey=[3,3]

I got a wrong results of:

-3x-3 -3x-2 -3x-1 -3x0 -3x1 -3x2 -3x3 <-- should not display this part --> -3x4 -3x5 -3x6 -3x7 -3x8 -3x9 -3x10 <-- end of should not display this part --> ..... up to 3x3

to give you a better understanding of my project here is the screenshot of that I want to be made: Oops they don't allowed new poster to post an image img96(dot)imageshack(dot)us/img96/5382/coordinates(dot)jpg <<< just change the "(dot)" to "."

+1  A: 
by_range?startkey=[-3,-3]&endkey=[3,3]

You are using this like a WHERE clause. Couchdb does not understand the values in "startkey" and "endkey", it just uses them to know when to start and stop outputting results.

For example, take the following result set:

doc1
doc2
doc3
doc4

If I apply this query:

?startkey=doc2&endkey=doc3

The result set would be:

doc2
doc3

To apply a range in your example, I would modify the map function:

function(doc) {
 if (doc.x <= 3 && doc.x >= -3 && doc.y <= 3 && doc.y >= -3)
   emit([doc.x, doc.y], doc)
}

Update to handle dynamic ranges:

According to Database Queries the CouchDB Way:

"The CouchDB design gets you great performance on large data sets. But it means that you cannot pass dynamic parameters to your map function when you run a query."

So to do a dynamic range, you need to alter the output of the key value to a single value so you can use startkey and endkey parameters.

function(doc) {
 emit(doc.x * doc.y, doc)
}

Use this filter:

by_range?startkey=-9&endkey=9

In your application you can calculate the start and end keys by doing something like

startkey = (x1*y1)
endkey = (x2*y2)
andyuk
Hi anduk, First of all, allow me to thank you on your quick reply. I see your point but the problem is the if condition you make is not dynamic meaning it only applicable to x/y -3 to 3. These numbers(-3 and 3) will be change depend on the selected part of the coordinates.Is there a way to pass a request parameter in this views? so it will become dynamic. something like function(doc, req) ? Thanks again!
Duasto
I've updated my post - hopefully that should solve it.
andyuk
A: 

Hi andyuk, Thanks again but the problem didn't solve because it gets other coordinates that should not get. I think problem is when we multiply the (x * y) some coordinates gets same key like:

(x * y)

3 * -3 = -9

9 * -1 = -9

So the 9x-1 coordinate should not be on the results and other coordinates that are not in the range of "(doc.x <= 3 && doc.x >= -3 && doc.y <= 3 && doc.y >= -3) ".

Thanks, Duasto

duasto
A: 

See these pages:

Basically 2 options:

  1. Use 2 seprate queries and merge the results.
  2. Use couchdb-lucene
andyuk
A: 

You can do something like a WHERE clause with multiple keys and the technique described in this article.

fuzzy lollipop