Class: ThinkingSphinx::Attribute
- Defined in:
- lib/thinking_sphinx/attribute.rb
Overview
Attributes - eternally useful when it comes to filtering, sorting or grouping. This class isn’t really useful to you unless you’re hacking around with the internals of Thinking Sphinx - but hey, don’t let that stop you.
One key thing to remember - if you’re using the attribute manually to generate SQL statements, you’ll need to set the base model, and all the associations. Which can get messy. Use Index.link!, it really helps.
Constant Summary collapse
- SphinxTypeMappings =
{ :multi => :sql_attr_multi, :datetime => :sql_attr_timestamp, :string => :sql_attr_str2ordinal, :float => :sql_attr_float, :boolean => :sql_attr_bool, :integer => :sql_attr_uint, :bigint => :sql_attr_bigint, :wordcount => :sql_attr_str2wordcount }
Instance Attribute Summary collapse
-
#query_source ⇒ Object
Returns the value of attribute query_source.
Attributes inherited from Property
#admin, #alias, #associations, #columns, #faceted, #model
Instance Method Summary collapse
- #all_datetimes? ⇒ Boolean
- #all_ints? ⇒ Boolean
- #all_strings? ⇒ Boolean
-
#config_value(offset = nil, delta = false) ⇒ Object
Returns the configuration value that should be used for the attribute.
- #include_as_association? ⇒ Boolean
-
#initialize(source, columns, options = {}) ⇒ Attribute
constructor
To create a new attribute, you’ll need to pass in either a single Column or an array of them, and some (optional) options.
- #live_value(instance) ⇒ Object
-
#to_select_sql ⇒ Object
Get the part of the SELECT clause related to this attribute.
-
#type ⇒ Object
Returns the type of the column.
- #type_to_config ⇒ Object
- #updatable? ⇒ Boolean
Methods inherited from Property
#admin?, #available?, #changed?, #public?, #to_facet, #to_group_sql, #unique_name
Constructor Details
#initialize(source, columns, options = {}) ⇒ Attribute
To create a new attribute, you’ll need to pass in either a single Column or an array of them, and some (optional) options.
Valid options are:
-
:as => :alias_name
-
:type => :attribute_type
-
:source => :field, :query, :ranged_query
Alias is only required in three circumstances: when there’s another attribute or field with the same name, when the column name is ‘id’, or when there’s more than one column.
Type is not required, unless you want to force a column to be a certain type (but keep in mind the value will not be CASTed in the SQL statements). The only time you really need to use this is when the type can’t be figured out by the column - ie: when not actually using a database column as your source.
Source is only used for multi-value attributes (MVA). By default this will use a left-join and a group_concat to obtain the values. For better performance during indexing it can be beneficial to let Sphinx use a separate query to retrieve all document,value-pairs. Either :query or :ranged_query will enable this feature, where :ranged_query will cause the query to be executed incremental.
Example usage:
Attribute.new(
Column.new(:created_at)
)
Attribute.new(
Column.new(:posts, :id),
:as => :post_ids
)
Attribute.new(
Column.new(:posts, :id),
:as => :post_ids,
:source => :ranged_query
)
Attribute.new(
[Column.new(:pages, :id), Column.new(:articles, :id)],
:as => :content_ids
)
Attribute.new(
Column.new("NOW()"),
:as => :indexed_at,
:type => :datetime
)
If you’re creating attributes for latitude and longitude, don’t forget that Sphinx expects these values to be in radians.
85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/thinking_sphinx/attribute.rb', line 85 def initialize(source, columns, = {}) super @type = [:type] @query_source = [:source] @crc = [:crc] @type ||= :multi unless @query_source.nil? if @type == :string && @crc @type = is_many? ? :multi : :integer end source.attributes << self end |
Instance Attribute Details
#query_source ⇒ Object
Returns the value of attribute query_source.
12 13 14 |
# File 'lib/thinking_sphinx/attribute.rb', line 12 def query_source @query_source end |
Instance Method Details
#all_datetimes? ⇒ Boolean
202 203 204 |
# File 'lib/thinking_sphinx/attribute.rb', line 202 def all_datetimes? all_of_type?(:datetime, :date, :timestamp) end |
#all_ints? ⇒ Boolean
198 199 200 |
# File 'lib/thinking_sphinx/attribute.rb', line 198 def all_ints? all_of_type?(:integer) end |
#all_strings? ⇒ Boolean
206 207 208 |
# File 'lib/thinking_sphinx/attribute.rb', line 206 def all_strings? all_of_type?(:string, :text) end |
#config_value(offset = nil, delta = false) ⇒ Object
Returns the configuration value that should be used for the attribute. Special case is the multi-valued attribute that needs some extra configuration.
147 148 149 150 151 152 153 154 155 |
# File 'lib/thinking_sphinx/attribute.rb', line 147 def config_value(offset = nil, delta = false) if type == :multi multi_config = include_as_association? ? "field" : source_value(offset, delta).gsub(/\s+/m, " ").strip "uint #{unique_name} from #{multi_config}" else unique_name end end |
#include_as_association? ⇒ Boolean
138 139 140 |
# File 'lib/thinking_sphinx/attribute.rb', line 138 def include_as_association? ! (type == :multi && (query_source == :query || query_source == :ranged_query)) end |
#live_value(instance) ⇒ Object
187 188 189 190 191 192 193 194 195 196 |
# File 'lib/thinking_sphinx/attribute.rb', line 187 def live_value(instance) object = instance column = @columns.first column.__stack.each { |method| object = object.send(method) return sphinx_value(nil) if object.nil? } sphinx_value object.send(column.__name) end |
#to_select_sql ⇒ Object
Get the part of the SELECT clause related to this attribute. Don’t forget to set your model and associations first though.
This will concatenate strings and arrays of integers, and convert datetimes to timestamps, as needed.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/thinking_sphinx/attribute.rb', line 106 def to_select_sql return nil unless include_as_association? && available? separator = all_ints? || all_datetimes? || @crc ? ',' : ' ' clause = columns_with_prefixes.collect { |column| case type when :string adapter.convert_nulls(column) when :datetime adapter.cast_to_datetime(column) when :multi column = adapter.cast_to_datetime(column) if is_many_datetimes? column = adapter.convert_nulls(column, '0') if is_many_ints? column else column end }.join(', ') clause = adapter.crc(clause) if @crc clause = adapter.concatenate(clause, separator) if concat_ws? clause = adapter.group_concatenate(clause, separator) if is_many? clause = adapter.downcase(clause) if insensitive? "#{clause} AS #{quote_column(unique_name)}" end |
#type ⇒ Object
Returns the type of the column. If that’s not already set, it returns :multi if there’s the possibility of more than one value, :string if there’s more than one association, otherwise it figures out what the actual column’s datatype is and returns that.
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/thinking_sphinx/attribute.rb', line 162 def type @type ||= begin base_type = case when is_many?, is_many_ints? :multi when @associations.values.flatten.length > 1 :string else translated_type_from_database end if base_type == :string && @crc base_type = :integer else @crc = false unless base_type == :multi && is_many_strings? && @crc end base_type end end |
#type_to_config ⇒ Object
134 135 136 |
# File 'lib/thinking_sphinx/attribute.rb', line 134 def type_to_config SphinxTypeMappings[type] end |
#updatable? ⇒ Boolean
183 184 185 |
# File 'lib/thinking_sphinx/attribute.rb', line 183 def updatable? [:integer, :datetime, :boolean].include?(type) && !is_string? end |