Reputation: 12112
I want to group documents in rethinkdb by price range (0-100, 100-200, 200-300, and so on), instead of a single price value. How do I do that?
Upvotes: 0
Views: 127
Reputation: 371
Unfortunately, ReQL doesn't support rounding at the moment (see github issue #866), but you can get something similar through some minor annoyances.
First of all, I would recommend making this an index on the given table if you're going to be running this regularly or on large data sets. The function I have here is not the most efficient because we can't round numbers, and an index would help mitigate that a lot.
These code samples are in Python, since I didn't see any particular language referenced. To create the index, run something like:
r.db('foo').table('bar').index_create('price_range',
lambda row: row['price'].coerce_to('STRING').split('.')[0].coerce_to('NUMBER')
.do(lambda x: x.sub(x.mod(100)))).run()
This will create a secondary index based on the price where 0
indicates [0-100)
, 100
is [100-200)
, and so on. At this point, a group-by is trivial:
r.db('foo').table('bar').group(index='price_range').run()
If you would really rather not create an index, the mapping can be done during the group
in a single query:
r.db('foo').table('bar').group(
lambda row: row['price'].coerce_to('STRING').split('.')[0].coerce_to('NUMBER')
.do(lambda x: x.sub(x.mod(100)))).run()
This query is fairly straight-forward, but to document what is going on:
coerce_to('STRING')
- we obtain a string representation of the number, e.g. 318.12
becomes "318.12"
.split('.')
- we split the string on the decimal point, e.g. "318.12"
. becomes ["318", "12"]
. If there is no decimal point, everything else should still work.[0]
- we take the first value of the split string, which is equivalent the original number rounded down. e.g. "318"
.coerce_to('NUMBER')
- we convert the string back into an integer, which allows us to do modulo arithmetic on it so we can round, e.g. "318"
becomes 318
..do(lambda x: x.sub(x.mod(100)))
- we round the resulting integer down to the nearest 100 by running (essentially) x = x - (x % 100)
, e.g. 318
becomes 300
.Upvotes: 1