xapit 0.2.4 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,12 @@
1
+ *0.2.5* (June 26th, 2009)
2
+
3
+ * adding wildcard matching for general search query (ClassicQueryParser only)
4
+
5
+ * adding wildcard matching when asterisk exists at end of condition
6
+
7
+ :conditions => { :name => "foo*" }
8
+
9
+
1
10
  *0.2.4* (June 23rd, 2009)
2
11
 
3
12
  * only create/update record in index if it matches xapit find conditions
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
2
2
  require 'rake'
3
3
  require 'echoe'
4
4
 
5
- Echoe.new('xapit', '0.2.4') do |p|
5
+ Echoe.new('xapit', '0.2.5') do |p|
6
6
  p.summary = "Ruby library for interacting with Xapian, a full text search engine."
7
7
  p.description = "Ruby library for interacting with Xapian, a full text search engine."
8
8
  p.url = "http://github.com/ryanb/xapit"
@@ -73,3 +73,39 @@ Scenario: Query Range of Integer
73
73
  | Jack | 24 |
74
74
  When I query "age" between 8 and 15
75
75
  Then I should find records named "John, Jane"
76
+
77
+ Scenario: Query Partial Match on Condition
78
+ Given the following indexed records
79
+ | name | sirname |
80
+ | John | Jacobson |
81
+ | Jane | Niel |
82
+ | Jack | Striker |
83
+ When I query "name" matching "Ja*"
84
+ Then I should find records named "Jane, Jack"
85
+
86
+ Scenario: Query no partial match on conditions with one letter
87
+ Given the following indexed records
88
+ | name | sirname |
89
+ | John | Jacobson |
90
+ | Jane | Niel |
91
+ | Jack | Striker |
92
+ When I query "name" matching " J*"
93
+ Then I should find 0 records
94
+
95
+ Scenario: Query partial match in keywords
96
+ Given the following indexed records
97
+ | name | sirname |
98
+ | John | Jacobson |
99
+ | Bill | Niel |
100
+ | Jack | Striker |
101
+ When I query for "Ja*"
102
+ Then I should find records named "John, Jack"
103
+
104
+ Scenario: Query no partial match in keywords with one letter
105
+ Given the following indexed records
106
+ | name | sirname |
107
+ | John | Jacobson |
108
+ | Bill | Niel |
109
+ | Jack | J |
110
+ When I query for " J*"
111
+ Then I should find records named "Jack"
@@ -89,6 +89,9 @@ module Xapit
89
89
  # # no need to specify first query string when searching all records
90
90
  # @articles = Article.search(:conditions => { :category_id => params[:category_id] })
91
91
  #
92
+ # # search partial terms with asterisk (only supported at end of term)
93
+ # @articles = Article.search("sab*", :conditions => { :name => "Din*" })
94
+ #
92
95
  def search(*args)
93
96
  Collection.new(self, *args)
94
97
  end
@@ -126,6 +126,8 @@ module Xapit
126
126
  if value.kind_of?(Range) && @member_class
127
127
  position = @member_class.xapit_index_blueprint.position_of_field(name)
128
128
  Xapian::Query.new(Xapian::Query::OP_VALUE_RANGE, position, Xapit.serialize_value(value.begin), Xapit.serialize_value(value.end))
129
+ elsif value.to_s.ends_with?("*") && value.to_s.strip.length > 2
130
+ wildcard_query(value, "X#{name}-")
129
131
  else
130
132
  if value.kind_of? Time
131
133
  value = value.to_i
@@ -135,5 +137,14 @@ module Xapit
135
137
  "X#{name}-#{value.to_s.downcase}"
136
138
  end
137
139
  end
140
+
141
+ # Expands the wildcard in the term (just at the end) and returns a query
142
+ # which will match any term that starts with the given term.
143
+ def wildcard_query(term, prefix = "")
144
+ partial_term = term.sub(/\*$/, '') # remove asterisk at end if it exists
145
+ parser = Xapian::QueryParser.new
146
+ parser.database = Xapit::Config.database
147
+ parser.parse_query(partial_term, Xapian::QueryParser::FLAG_PARTIAL, prefix)
148
+ end
138
149
  end
139
150
  end
@@ -1,15 +1,20 @@
1
1
  module Xapit
2
2
  class ClassicQueryParser < AbstractQueryParser
3
3
  def xapian_query_from_text(text)
4
- xapian_parser.parse_query(text)
4
+ xapian_parser.parse_query(cleanup_text(text), Xapian::QueryParser::FLAG_WILDCARD | Xapian::QueryParser::FLAG_PHRASE | Xapian::QueryParser::FLAG_BOOLEAN | Xapian::QueryParser::FLAG_LOVEHATE)
5
5
  end
6
6
 
7
7
  def xapian_parser
8
8
  @xapian_parser ||= build_xapian_parser
9
9
  end
10
10
 
11
+ def cleanup_text(text)
12
+ text.gsub(/\b([a-z])\*/i) { $1 }
13
+ end
14
+
11
15
  def build_xapian_parser
12
16
  parser = Xapian::QueryParser.new
17
+ parser.database = Config.database
13
18
  parser.stemmer = Xapian::Stem.new(Config.stemming)
14
19
  parser.stemming_strategy = Xapian::QueryParser::STEM_SOME
15
20
  parser.default_op = Xapian::Query::OP_AND
@@ -6,10 +6,15 @@ describe Xapit::ClassicQueryParser do
6
6
  end
7
7
 
8
8
  it "should have an initial xapian parser with stemming and default operator support" do
9
+ Xapit::Config.writable_database # just so a database exists
9
10
  expected = Xapian::QueryParser.new
10
11
  expected.stemmer = Xapian::Stem.new("english")
11
12
  expected.stemming_strategy = Xapian::QueryParser::STEM_SOME
12
13
  expected.default_op = Xapian::Query::OP_AND
13
14
  @parser.xapian_query_from_text("foo bar").description.should == expected.parse_query("foo bar").description
14
15
  end
16
+
17
+ it "should remove asterisks from terms with one letter" do
18
+ @parser.cleanup_text("J*").should == "J"
19
+ end
15
20
  end
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{xapit}
5
- s.version = "0.2.4"
5
+ s.version = "0.2.5"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Ryan Bates"]
9
- s.date = %q{2009-06-23}
9
+ s.date = %q{2009-06-26}
10
10
  s.description = %q{Ruby library for interacting with Xapian, a full text search engine.}
11
11
  s.email = %q{ryan (at) railscasts (dot) com}
12
12
  s.extra_rdoc_files = ["CHANGELOG", "lib/xapit/adapters/abstract_adapter.rb", "lib/xapit/adapters/active_record_adapter.rb", "lib/xapit/adapters/data_mapper_adapter.rb", "lib/xapit/collection.rb", "lib/xapit/config.rb", "lib/xapit/facet.rb", "lib/xapit/facet_blueprint.rb", "lib/xapit/facet_option.rb", "lib/xapit/index_blueprint.rb", "lib/xapit/indexers/abstract_indexer.rb", "lib/xapit/indexers/classic_indexer.rb", "lib/xapit/indexers/simple_indexer.rb", "lib/xapit/membership.rb", "lib/xapit/query.rb", "lib/xapit/query_parsers/abstract_query_parser.rb", "lib/xapit/query_parsers/classic_query_parser.rb", "lib/xapit/query_parsers/simple_query_parser.rb", "lib/xapit/rake_tasks.rb", "lib/xapit.rb", "LICENSE", "README.rdoc", "tasks/spec.rb", "tasks/xapit.rake", "TODO"]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xapit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Bates
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-06-23 00:00:00 -07:00
12
+ date: 2009-06-26 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15