problems with two key ranges in couchdb
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 scre开发者_StackOverflow社区enshot of that I want to be made:
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)
See these pages:
- multiple key ranges as parameters to a couchdb view
- Does CouchDB support multiple range queries?
- Help with complex key range query and map/reduce
Basically 2 options:
- Use 2 seprate queries and merge the results.
- Use couchdb-lucene
You can do something like a WHERE clause with multiple keys and the technique described in this article.
精彩评论