xapit 0.2.4 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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