Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NoBrainer::Error::CannotUseIndex on compound index with a range #207

Open
ajselvig opened this issue May 22, 2016 · 5 comments
Open

NoBrainer::Error::CannotUseIndex on compound index with a range #207

ajselvig opened this issue May 22, 2016 · 5 comments
Labels
enhancement Improve what already exist.

Comments

@ajselvig
Copy link
Contributor

Maybe this isn't possible with rethink, but I'm unable to use a compound index when one of the query parameters is using a range modifier (.gt, .lt, etc):

class Foo
  include NoBrainer::Document
  field :name, type: String
  field :time, type: Time
  index [:time, :name]
end

NoBrainer.sync_indexes

# works fine
Foo.where(name: 'foo', time: Time.now).with_index(:time_name).count

# raises NoBrainer::Error::CannotUseIndex
Foo.where(name: 'foo', :time.lt => Time.now).with_index(:time_name).count
@nviennot
Copy link
Collaborator

Hum... I'm not sure what would be the RethinkDB query that should be used in this case. Any idea?

@ajselvig
Copy link
Contributor Author

It seems like it should be possible based on the docs, but I'm having trouble getting it to work:

%w(foo bar).each do |name|
  t = Time.now - 1.day
  while t < Time.now+1.day
    Foo.create! name: name, time: t
    t += 1.hour
  end
end

puts Foo.where(name: 'foo', :time.lt => Time.now).count
# => 25 (correct)

c = NoBrainer.run do |r|
  r.table('foos').between(
      [r.minval, 'foo'], [Time.now, 'foo'], index: 'time_name'
  ).count
end
puts c
# => 50

It seems to be ignoring the name condition for some reason. I'll keep digging.

@ajselvig
Copy link
Contributor Author

It looks like it works if the index order is flipped around:

class Foo
  include NoBrainer::Document
  field :name, type: String
  field :time, type: Time
  index [:name, :time]
end

The result is then correct:

c = NoBrainer.run do |r|
  r.table('foos').between(
      ['foo', r.minval], ['foo', Time.now], index: 'name_time'
  ).count
end
puts c
# => 25

The explanation is here: https://rethinkdb.com/api/ruby/between/ in the "lexicographical order" part, although it's not entirely clear why it behaves this way.

This functionality would provide a pretty big performance boost since we have tables containing lots of records that are almost always queried by both a time range and a single foreign key value. Does it seem like something reasonable to support?

@nviennot
Copy link
Collaborator

That's reasonable. It might take me a bit of time to implement this as I have a lot of my plate these days.

@ajselvig
Copy link
Contributor Author

Yeah, no problem. Thanks.

@zedtux zedtux added the enhancement Improve what already exist. label Feb 6, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Improve what already exist.
Projects
None yet
Development

No branches or pull requests

3 participants