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 +9 -0
- data/Rakefile +1 -1
- data/features/finding.feature +36 -0
- data/lib/xapit/membership.rb +3 -0
- data/lib/xapit/query_parsers/abstract_query_parser.rb +11 -0
- data/lib/xapit/query_parsers/classic_query_parser.rb +6 -1
- data/spec/xapit/query_parsers/classic_query_parser_spec.rb +5 -0
- data/xapit.gemspec +2 -2
- metadata +2 -2
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.
|
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"
|
data/features/finding.feature
CHANGED
@@ -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"
|
data/lib/xapit/membership.rb
CHANGED
@@ -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
|
data/xapit.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{xapit}
|
5
|
-
s.version = "0.2.
|
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-
|
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
|
+
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-
|
12
|
+
date: 2009-06-26 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|