From 7f7a4a21c5af6f64d91f9b56867eef0c6b46f2e3 Mon Sep 17 00:00:00 2001 From: Curtis Hatter Date: Wed, 28 Aug 2013 01:43:49 -0400 Subject: [PATCH 1/4] regexp query initial commit, with tests --- README.markdown | 8 ++++++ lib/tire/queries/regexp.rb | 46 ++++++++++++++++++++++++++++++ lib/tire/queries/regexp/regexp.rb | 25 ++++++++++++++++ test/queries/regexp/regexp_test.rb | 40 ++++++++++++++++++++++++++ 4 files changed, 119 insertions(+) create mode 100644 lib/tire/queries/regexp.rb create mode 100644 lib/tire/queries/regexp/regexp.rb create mode 100644 test/queries/regexp/regexp_test.rb diff --git a/README.markdown b/README.markdown index c84b107..edc0913 100644 --- a/README.markdown +++ b/README.markdown @@ -27,6 +27,14 @@ 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. +### Fuzzy Like This 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. + ### Custom Filters Score ### Adds support for [“custom filters score”](http://www.elasticsearch.org/guide/reference/query-dsl/custom-filters-score-query.html) queries. diff --git a/lib/tire/queries/regexp.rb b/lib/tire/queries/regexp.rb new file mode 100644 index 0000000..f0aa341 --- /dev/null +++ b/lib/tire/queries/regexp.rb @@ -0,0 +1,46 @@ +# Regexp +# ============== +# +# Author: Curtis Hatter +# +# +# 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 +# wildcard "name.first", 's.*y', boost: 1.2, flags: [:intersection, :complement, :empty] +# end +# end +# +# For more about this query: +# +# * +# +# +require 'tire/queries/regexp/regexp' + +Tire::Search::Query.class_eval do + include Tire::Search::Regexp +end diff --git a/lib/tire/queries/regexp/regexp.rb b/lib/tire/queries/regexp/regexp.rb new file mode 100644 index 0000000..f4836f2 --- /dev/null +++ b/lib/tire/queries/regexp/regexp.rb @@ -0,0 +1,25 @@ +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] + (flags.map { |i| i.downcase.to_sym } & valid_flags).map { |i| i.to_s.upcase }.join('|') + end + end + end +end diff --git a/test/queries/regexp/regexp_test.rb b/test/queries/regexp/regexp_test.rb new file mode 100644 index 0000000..29fb1b7 --- /dev/null +++ b/test/queries/regexp/regexp_test.rb @@ -0,0 +1,40 @@ +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 + 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 \ No newline at end of file From 6c1967b858ceaa7914c0928357c9f762ebd7e755 Mon Sep 17 00:00:00 2001 From: Curtis Hatter Date: Wed, 28 Aug 2013 02:05:26 -0400 Subject: [PATCH 2/4] allow a single symbol to be passed in for flags instead of requiring an array with a single item --- lib/tire/queries/regexp/regexp.rb | 7 ++++++- test/queries/regexp/regexp_test.rb | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/tire/queries/regexp/regexp.rb b/lib/tire/queries/regexp/regexp.rb index f4836f2..c77d3af 100644 --- a/lib/tire/queries/regexp/regexp.rb +++ b/lib/tire/queries/regexp/regexp.rb @@ -18,7 +18,12 @@ def validate_regexp_options(options) def validate_regexp_flags(flags = []) valid_flags = [:all, :anystring, :automaton, :complement, :empty, :intersection, :interval, :none] - (flags.map { |i| i.downcase.to_sym } & valid_flags).map { |i| i.to_s.upcase }.join('|') + + 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 diff --git a/test/queries/regexp/regexp_test.rb b/test/queries/regexp/regexp_test.rb index 29fb1b7..1cedbd2 100644 --- a/test/queries/regexp/regexp_test.rb +++ b/test/queries/regexp/regexp_test.rb @@ -20,6 +20,11 @@ class RegexpTest < Test::Unit::TestCase 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 From bbf388dfc592bc7a2f49cf4f4959edc566a38de7 Mon Sep 17 00:00:00 2001 From: Curtis Hatter Date: Wed, 28 Aug 2013 02:08:50 -0400 Subject: [PATCH 3/4] fixed butchering of README.markdown --- README.markdown | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/README.markdown b/README.markdown index edc0913..cd2a3a2 100644 --- a/README.markdown +++ b/README.markdown @@ -27,7 +27,7 @@ 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. -### Fuzzy Like This Queries ### +### Regular Expression Queries ### Adds support for [“regexp”](http://www.elasticsearch.org/guide/reference/query-dsl/regexp-query/) queries. @@ -35,10 +35,6 @@ Adds support for [“regexp”](http://www.elasticsearch.org/guide/reference/que Adds support for [“custom filters score”](http://www.elasticsearch.org/guide/reference/query-dsl/custom-filters-score-query.html) queries. -### Custom Filters Score ### - -Adds support for [“custom filters score”](http://www.elasticsearch.org/guide/reference/query-dsl/custom-filters-score-query.html) queries. - ### Rails Logger ### Adds support for displaying Tire related statistics in the Rails' log. From 74724e9137da1394d94e402c85d0638726b67259 Mon Sep 17 00:00:00 2001 From: Curtis Hatter Date: Wed, 28 Aug 2013 20:47:44 -0400 Subject: [PATCH 4/4] fix typo in regexp.rb --- lib/tire/queries/regexp.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tire/queries/regexp.rb b/lib/tire/queries/regexp.rb index f0aa341..1fe5236 100644 --- a/lib/tire/queries/regexp.rb +++ b/lib/tire/queries/regexp.rb @@ -30,7 +30,7 @@ # # Tire.search 'articles' do # query do -# wildcard "name.first", 's.*y', boost: 1.2, flags: [:intersection, :complement, :empty] +# regexp "name.first", 's.*y', boost: 1.2, flags: [:intersection, :complement, :empty] # end # end #