forked from tomasc/sunspot_cell
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 03941c9
Showing
12 changed files
with
392 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
WIP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
require 'lib/sunspot' | ||
require 'lib/composite_setup' | ||
require 'lib/sunspot/dsl/fields' | ||
require 'lib/sunspot/dsl/standard_query' | ||
require 'lib/sunspot/type' | ||
require 'lib/sunspot/field' | ||
require 'lib/sunspot/setup' | ||
require 'lib/sunspot/field_factory' | ||
require 'lib/sunspot/indexer' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
module Sunspot | ||
class CompositeSetup | ||
|
||
# Collection of all attachment fields configured for any of the enclosed types. | ||
# | ||
# === Returns | ||
# | ||
# Array:: Text fields configured for the enclosed types | ||
# | ||
def all_attachment_fields | ||
@attachment_fields ||= attachment_fields_hash.values.map { |set| set.to_a }.flatten | ||
end | ||
|
||
private | ||
|
||
# Return a hash of field names to atachment field objects, containing all fields | ||
# that are configured for any of the types enclosed. | ||
# | ||
# ==== Returns | ||
# | ||
# Hash:: Hash of field names to text field objects. | ||
# | ||
def attachment_fields_hash | ||
@attachment_fields_hash ||= | ||
setups.inject({}) do |hash, setup| | ||
setup.all_attachment_fields.each do |text_field| | ||
(hash[text_field.name] ||= Set.new) << text_field | ||
end | ||
hash | ||
end | ||
end | ||
|
||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
%w(rich_document).each do |filename| | ||
require File.join(File.dirname(__FILE__), 'sunspot', filename) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
module Sunspot | ||
module DSL | ||
class Fields | ||
|
||
# Added an attachment field, the attachment filename is passed to Solr for | ||
# indexing by tiqa | ||
|
||
def attachment(*names) | ||
names.each do |name| | ||
@setup.add_attachment_field_factory(name) | ||
end | ||
end | ||
|
||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
module Sunspot | ||
module DSL #:nodoc: | ||
# | ||
# This class presents a DSL for constructing queries using the | ||
# Sunspot.search method. Methods of this class are available inside the | ||
# search block. Much of the DSL's functionality is implemented by this | ||
# class's superclasses, Sunspot::DSL::FieldQuery and Sunspot::DSL::Scope | ||
# | ||
# See Sunspot.search for usage examples | ||
# | ||
class StandardQuery < FieldQuery | ||
include Paginatable, Adjustable | ||
|
||
# Specify a phrase that should be searched as fulltext. Only +text+ | ||
# fields are searched - see DSL::Fields.text | ||
# | ||
# Keyword search is executed using Solr's dismax handler, which strikes | ||
# a good balance between powerful and foolproof. In particular, | ||
# well-matched quotation marks can be used to group phrases, and the | ||
# + and - modifiers work as expected. All other special Solr boolean | ||
# syntax is escaped, and mismatched quotes are ignored entirely. | ||
# | ||
# This method can optionally take a block, which is evaluated by the | ||
# Fulltext DSL class, and exposes several powerful dismax features. | ||
# | ||
# ==== Parameters | ||
# | ||
# keywords<String>:: phrase to perform fulltext search on | ||
# | ||
# ==== Options | ||
# | ||
# :fields<Array>:: | ||
# List of fields that should be searched for keywords. Defaults to all | ||
# fields configured for the types under search. | ||
# :highlight<Boolean,Array>:: | ||
# If true, perform keyword highlighting on all searched fields. If an | ||
# array of field names, perform highlighting on the specified fields. | ||
# This can also be called from within the fulltext block. | ||
# :minimum_match<Integer>:: | ||
# The minimum number of search terms that a result must match. By | ||
# default, all search terms must match; if the number of search terms | ||
# is less than this number, the default behavior applies. | ||
# :tie<Float>:: | ||
# A tiebreaker coefficient for scores derived from subqueries that are | ||
# lower-scoring than the maximum score subquery. Typically a near-zero | ||
# value is useful. See | ||
# http://wiki.apache.org/solr/DisMaxRequestHandler#tie_.28Tie_breaker.29 | ||
# for more information. | ||
# :query_phrase_slop<Integer>:: | ||
# The number of words that can appear between the words in a | ||
# user-entered phrase (i.e., keywords in quotes) and still match. For | ||
# instance, in a search for "\"great pizza\"" with a phrase slop of 1, | ||
# "great pizza" and "great big pizza" will match, but "great monster of | ||
# a pizza" will not. Default behavior is a query phrase slop of zero. | ||
# | ||
def fulltext(keywords, options = {}, &block) | ||
if keywords && !(keywords.to_s =~ /^\s*$/) | ||
fulltext_query = @query.add_fulltext(keywords) | ||
if field_names = options.delete(:fields) | ||
Util.Array(field_names).each do |field_name| | ||
@setup.text_fields(field_name).each do |field| | ||
fulltext_query.add_fulltext_field(field, field.default_boost) | ||
end | ||
end | ||
end | ||
if minimum_match = options.delete(:minimum_match) | ||
fulltext_query.minimum_match = minimum_match.to_i | ||
end | ||
if tie = options.delete(:tie) | ||
fulltext_query.tie = tie.to_f | ||
end | ||
if query_phrase_slop = options.delete(:query_phrase_slop) | ||
fulltext_query.query_phrase_slop = query_phrase_slop.to_i | ||
end | ||
if highlight_field_names = options.delete(:highlight) | ||
if highlight_field_names == true | ||
fulltext_query.add_highlight | ||
else | ||
highlight_fields = [] | ||
Util.Array(highlight_field_names).each do |field_name| | ||
highlight_fields.concat(@setup.text_fields(field_name)) | ||
end | ||
fulltext_query.add_highlight(highlight_fields) | ||
end | ||
end | ||
if block && fulltext_query | ||
fulltext_dsl = Fulltext.new(fulltext_query, @setup) | ||
Util.instance_eval_or_call( | ||
fulltext_dsl, | ||
&block | ||
) | ||
end | ||
if !field_names && (!fulltext_dsl || !fulltext_dsl.fields_added?) | ||
@setup.all_text_fields.each do |field| | ||
unless fulltext_query.has_fulltext_field?(field) | ||
unless fulltext_dsl && fulltext_dsl.exclude_fields.include?(field.name) | ||
fulltext_query.add_fulltext_field(field, field.default_boost) | ||
end | ||
end | ||
end | ||
end | ||
if !field_names && (!fulltext_dsl || !fulltext_dsl.fields_added?) | ||
unless @setup.all_attachment_fields.empty? | ||
@setup.all_attachment_fields.each do |attachment_text_field| | ||
unless fulltext_dsl && fulltext_dsl.exclude_fields.include?(attachment_text_field.name) | ||
fulltext_query.add_fulltext_field(attachment_text_field, attachment_text_field.default_boost) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end | ||
alias_method :keywords, :fulltext | ||
|
||
def with(*args) | ||
case args.first | ||
when String, Symbol | ||
field_name = args[0] | ||
value = args.length > 1 ? args[1] : Scope::NONE | ||
if value == Scope::NONE | ||
return DSL::RestrictionWithNear.new(@setup.field(field_name.to_sym), @scope, @query, false) | ||
end | ||
end | ||
|
||
# else | ||
super | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module Sunspot | ||
class Field | ||
attr_reader :default_boost | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
module Sunspot | ||
module FieldFactory | ||
|
||
class Attachment | ||
def initialize(name = nil, &block) | ||
if block | ||
@data_extractor = DataExtractor::BlockExtractor.new(&block) | ||
else | ||
@data_extractor = DataExtractor::AttributeExtractor.new(name) | ||
end | ||
end | ||
|
||
def populate_document(document, model) | ||
end | ||
end | ||
|
||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
module Sunspot | ||
class Indexer | ||
|
||
def add_documents(documents) | ||
documents_arr = Util.Array(documents) | ||
docs_attach = [] | ||
docs_no_attach = [] | ||
documents_arr.each do |document| | ||
if document.contains_attachment? | ||
docs_attach << document | ||
else | ||
docs_no_attach << document | ||
end | ||
end | ||
|
||
unless docs_no_attach.empty? | ||
@connection.add(docs_no_attach) | ||
else | ||
Util.Array(docs_attach).each do |document| | ||
document.add(@connection) | ||
end | ||
end | ||
end | ||
|
||
|
||
def document_for(model) | ||
Sunspot::RichDocument.new( | ||
:id => Adapters::InstanceAdapter.adapt(model).index_id, | ||
:type => Util.superclasses_for(model.class).map { |clazz| clazz.name } | ||
) | ||
end | ||
|
||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
module Sunspot | ||
class RichDocument < RSolr::Message::Document | ||
include Enumerable | ||
|
||
def contains_attachment? | ||
@fields.each do |field| | ||
if field.name.to_s.include?("_attachment") | ||
return true | ||
end | ||
end | ||
return false | ||
end | ||
|
||
|
||
|
||
def add(connection) | ||
params = { | ||
:wt => :ruby | ||
} | ||
|
||
data = nil | ||
|
||
@fields.each do |f| | ||
if f.name.to_s.include?("_attachment") and f.value.present? | ||
data = f.value.data | ||
params['fmap.content'] = f.name | ||
else | ||
param_name = "literal.#{f.name.to_s}" | ||
params[param_name] = [] unless params.has_key?(param_name) | ||
params[param_name] << f.value | ||
end | ||
if f.attrs[:boost] | ||
params["boost.#{f.name.to_s}"] = f.attrs[:boost] | ||
end | ||
end | ||
|
||
solr_message = params | ||
connection.send('update/extract', solr_message, data) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
module Sunspot | ||
class Setup | ||
|
||
def initialize(clazz) | ||
@class_object_id = clazz.object_id | ||
@class_name = clazz.name | ||
@field_factories, @text_field_factories, @dynamic_field_factories, @attachment_field_factories, | ||
@field_factories_cache, @text_field_factories_cache, | ||
@dynamic_field_factories_cache, @attachment_field_factories_cache = *Array.new(8) { Hash.new } | ||
@stored_field_factories_cache = Hash.new { |h, k| h[k] = [] } | ||
@more_like_this_field_factories_cache = Hash.new { |h, k| h[k] = [] } | ||
@dsl = DSL::Fields.new(self) | ||
add_field_factory(:class, Type::ClassType.instance) | ||
end | ||
|
||
|
||
|
||
# Add field_factories for fulltext search on attachments | ||
# | ||
# ==== Parameters | ||
# | ||
def add_attachment_field_factory(name, options = {}, &block) | ||
stored = options[:stored] | ||
field_factory = FieldFactory::Static.new(name, Type::AttachmentType.instance, options, &block) | ||
@attachment_field_factories[name] = field_factory | ||
@attachment_field_factories_cache[field_factory.name] = field_factory | ||
if stored | ||
@attachment_field_factories_cache[field_factory.name] << field_factory | ||
end | ||
end | ||
|
||
|
||
|
||
def text_fields(field_name) | ||
text_field = | ||
if field_factory = @text_field_factories_cache[field_name.to_sym] | ||
field_factory.build | ||
else | ||
if field_factory = @attachment_field_factories_cache[field_name.to_sym] | ||
field_factory.build | ||
else | ||
raise( | ||
UnrecognizedFieldError, | ||
"No text field configured for #{@class_name} with name '#{field_name}'" | ||
) | ||
end | ||
end | ||
[text_field] | ||
end | ||
|
||
|
||
|
||
def all_attachment_fields | ||
attachment_field_factories.map { |field_factory| field_factory.build } | ||
end | ||
|
||
|
||
|
||
# Get the text field_factories associated with this setup as well as all inherited | ||
# attachment field_factories | ||
# | ||
# ==== Returns | ||
# | ||
# Array:: Collection of all text field_factories associated with this setup | ||
# | ||
def attachment_field_factories | ||
collection_from_inheritable_hash(:attachment_field_factories) | ||
end | ||
|
||
|
||
def all_field_factories | ||
all_field_factories = [] | ||
all_field_factories.concat(field_factories).concat(text_field_factories).concat(dynamic_field_factories).concat(attachment_field_factories) | ||
all_field_factories | ||
end | ||
|
||
end | ||
end |
Oops, something went wrong.