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

Regexp query #30

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ Adds support for [“more like this”](http://www.elasticsearch.org/guide/refer

Adds support for [“fuzzy like this”](http://www.elasticsearch.org/guide/reference/query-dsl/flt-query.html) queries.

### Regular Expression Queries ###

Adds support for [“regexp”](http://www.elasticsearch.org/guide/reference/query-dsl/regexp-query/) queries.

### Custom Filters Score ###

Adds support for [“custom filters score”](http://www.elasticsearch.org/guide/reference/query-dsl/custom-filters-score-query.html) queries.
Expand Down
46 changes: 46 additions & 0 deletions lib/tire/queries/regexp.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Regexp
# ==============
#
# Author: Curtis Hatter <[email protected]>
#
#
# Adds support for "regexp" queries in Tire DSL.
#
# It hooks into the Query class and inserts the regexp query type.
#
#
# Usage:
# ------
#
# Require the component:
#
# require 'tire/queries/regexp'
#
# From that point on you should have the regexp query available.
#
#
# Example:
# -------
#
# Tire.search 'articles' do
# query do
# regexp "name.first", 's.*y'
# end
# end
#
# Tire.search 'articles' do
# query do
# regexp "name.first", 's.*y', boost: 1.2, flags: [:intersection, :complement, :empty]
# end
# end
#
# For more about this query:
#
# * <http://www.elasticsearch.org/guide/reference/query-dsl/regexp-query/>
#
#
require 'tire/queries/regexp/regexp'

Tire::Search::Query.class_eval do
include Tire::Search::Regexp
end
30 changes: 30 additions & 0 deletions lib/tire/queries/regexp/regexp.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module Tire
module Search
module Regexp
def regexp(field, text, options = {})
@value = {:regexp => { field => { value: text } } }
@value[:regexp][field].update(validate_regexp_options(options))
@value
end

private
def validate_regexp_options(options)
valid_options = [:boost, :flags]
options.delete_if { |key, value| !valid_options.member? key }

options[:flags] = validate_regexp_flags(options[:flags]) if options.member?(:flags)
options
end

def validate_regexp_flags(flags = [])
valid_flags = [:all, :anystring, :automaton, :complement, :empty, :intersection, :interval, :none]

if flags.is_a?(Array)
(flags.map { |i| i.downcase.to_sym } & valid_flags).map { |i| i.to_s.upcase }.join('|')
else
flags.to_s.upcase if valid_flags.member?(flags)
end
end
end
end
end
45 changes: 45 additions & 0 deletions test/queries/regexp/regexp_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
require 'tire'
require 'tire/queries/regexp'
require 'shoulda'

module Tire
module Search
class RegexpTest < Test::Unit::TestCase

context "Regexp queries" do
should "search for documents that have fields matching a regular expression" do
assert_equal({:regexp => {'name.first' => { :value => 's.*y'}}}, Query.new.regexp('name.first', 's.*y'))
end

should "allow to boost a regexp query" do
assert_equal({:regexp => {'name.first' => { :value => 's.*y', :boost => 2.0}}},
Query.new.regexp("name.first", 's.*y', :boost => 2.0))
end

should "allow to use special flags" do
assert_equal({:regexp => {'name.first' => { :value => 's.*y', :flags => 'INTERSECTION|COMPLEMENT|EMPTY'}}},
Query.new.regexp('name.first', 's.*y', :flags => [:intersection, :complement, :empty]))
end

should "allow to pass in only one flag" do
assert_equal({:regexp => {'name.first' => { :value => 's.*y', :flags => 'ALL' }}},
Query.new.regexp('name.first', 's.*y', :flags => :all))
end
end

context "validate the options passed" do
should "drop all the invalid keys" do
assert_equal({:regexp => {'name.first' => {:value => 's.*y', :boost => 2.0}}},
Query.new.regexp('name.first', 's.*y', :boost => 2.0, :foo => :bar))
assert_equal({:regexp => {'name.first' => {:value => 's.*y', :boost => 2.0}}},
Query.new.regexp('name.first', 's.*y', :boost => 2.0, :fields => [:bar]))
end

should "drop all the invalid flags" do
assert_equal({:regexp => {'name.first' => {:value => 's.*y', :flags => 'INTERSECTION|COMPLEMENT|EMPTY'}}},
Query.new.regexp('name.first', 's.*y', :flags => [:intersection, :bar, :baz, :complement, :empty]))
end
end
end
end
end