如何在 has-many :through 关系中对特定字段执行太阳黑子搜索
How do you perform a sunspot search on a specific field in a has-many :through relationship
假设使用以下示例作为基础...如果设置不正确,请纠正我。
迁移文件:
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :first_name, null: false
t.string :last_name, null: false
t.string :email, null: false
t.timestamps null: false
end
end
end
User.create(first_name:'John', last_name:'Smith', email:'john@smith.com') # id: 1
User.create(first_name:'Jane', last_name:'Smith', email:'jane@smith.com') # id: 2
class CreateCustomAttributes < ActiveRecord::Migration
def change
create_table :custom_attributes do |t|
t.string :name, null: false
t.text :description, null: true
t.timestamps null: false
end
end
end
CustomAttribute.create(name:'is_married', description:'') # id: 1
CustomAttribute.create(name:'has_children', description:'') # id: 2
CustomAttribute.create(name:'number_of_children', description:'') # id: 3
class CreateUserCustomAttributes < ActiveRecord::Migration
def change
create_table :user_custom_attributes do |t|
t.references :user, null: false
t.references :custom_attribute, null: false
t.text :value, null: true
t.timestamps null: false
end
end
end
# John
UserCustomAttribute.create(user_id: 1, custom_attribute_id: 1, value: 'no')
UserCustomAttribute.create(user_id: 1, custom_attribute_id: 2, value: 'yes')
UserCustomAttribute.create(user_id: 1, custom_attribute_id: 3, value: 4)
# Jane
UserCustomAttribute.create(user_id: 2, custom_attribute_id: 1, value: 'no')
UserCustomAttribute.create(user_id: 2, custom_attribute_id: 2, value: 'no')
UserCustomAttribute.create(user_id: 2, custom_attribute_id: 3, value: 0)
型号:
class CustomAttribute < ActiveRecord::Base
has_many :user_custom_attributes, :dependent => :destroy
has_many :users, through: :user_custom_attributes
end
class UserCustomAttribute < ActiveRecord::Base
belongs_to :user
belongs_to :custom_attribute
end
class User < ActiveRecord::Base
has_many :user_custom_attributes, :dependent => :destroy
has_many :custom_attributes, through: :user_custom_attributes
searchable do
text :first_name, :last_name, :email
end
end
我试图让 "value" 是动态的,无论它是简单的布尔值 (0,1)、字符串 ('speedy') 还是序列化的项目数组 ('-- -- 棒球-橄榄球')
是否可以搜索所有 children 的用户(例如 'has_children' 设置为 'yes')?
例如:/users?fq[has_children]=yes
此外,是否可以搜索具有 children 的所有用户(例如 'number_of_children' 大于 0)?
如果是这样,您将如何构建用户模型中的 'searchable' 块和 User.search 块?
做你想做的事情的最简单方法是首先分离出你想要的不同类型的动态字段(字符串、整数、布尔值),也许通过添加 attribute_type:'string', attribute_type: 'numerical', 等等 然后你可以使用Sunspot的动态字段来搜索不同类型的动态数据:
searchable do
dynamic_string :string_attributes do
user_custom_string_attributes.inject({}) do |hash, uca|
hash.merge(uca.custom_attribute.name.to_sym => uca.value)
end
end
dynamic_integer :numerical_attributes do
user_custom_numerical_attributes.inject({}) do |hash, nuca|
hash.merge(nuca.custom_attribute.name.to_sym => nuca.value.to_i) # just making sure it's an integer!
end
end
end
# Separate out the different types of attributes for different dynamic blocks
# via methods like the one below.
def user_custom_numerical_attributes
user_custom_attributes.where(attribute_type: 'numerical')
end
def user_custom_string_attributes
user_custom_attributes.where(attribute_type: 'string')
end
这将为您提供可搜索的 'string_attributes' 对象,这些对象看起来像 {:has_children => 'no'} 或 'numerical_attributes' 像 {:number_of_children => 2}.
然后你可以像这样用一个块搜索:
User.search do
dynamic :string_attributes do
with(:has_children, 'no')
end
dynamic :numerical_attributes do
with(:number_of_children).greater_than(0)
end
end
您可以为除文本之外的几乎任何数据类型创建动态字段;为此,您必须改用字符串。一旦设置了动态字段,在 dynamic :field_name do
块内,您可以使用 Sunspot readme.
示例中演示的任何非文本搜索方法
假设使用以下示例作为基础...如果设置不正确,请纠正我。
迁移文件:
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :first_name, null: false
t.string :last_name, null: false
t.string :email, null: false
t.timestamps null: false
end
end
end
User.create(first_name:'John', last_name:'Smith', email:'john@smith.com') # id: 1
User.create(first_name:'Jane', last_name:'Smith', email:'jane@smith.com') # id: 2
class CreateCustomAttributes < ActiveRecord::Migration
def change
create_table :custom_attributes do |t|
t.string :name, null: false
t.text :description, null: true
t.timestamps null: false
end
end
end
CustomAttribute.create(name:'is_married', description:'') # id: 1
CustomAttribute.create(name:'has_children', description:'') # id: 2
CustomAttribute.create(name:'number_of_children', description:'') # id: 3
class CreateUserCustomAttributes < ActiveRecord::Migration
def change
create_table :user_custom_attributes do |t|
t.references :user, null: false
t.references :custom_attribute, null: false
t.text :value, null: true
t.timestamps null: false
end
end
end
# John
UserCustomAttribute.create(user_id: 1, custom_attribute_id: 1, value: 'no')
UserCustomAttribute.create(user_id: 1, custom_attribute_id: 2, value: 'yes')
UserCustomAttribute.create(user_id: 1, custom_attribute_id: 3, value: 4)
# Jane
UserCustomAttribute.create(user_id: 2, custom_attribute_id: 1, value: 'no')
UserCustomAttribute.create(user_id: 2, custom_attribute_id: 2, value: 'no')
UserCustomAttribute.create(user_id: 2, custom_attribute_id: 3, value: 0)
型号:
class CustomAttribute < ActiveRecord::Base
has_many :user_custom_attributes, :dependent => :destroy
has_many :users, through: :user_custom_attributes
end
class UserCustomAttribute < ActiveRecord::Base
belongs_to :user
belongs_to :custom_attribute
end
class User < ActiveRecord::Base
has_many :user_custom_attributes, :dependent => :destroy
has_many :custom_attributes, through: :user_custom_attributes
searchable do
text :first_name, :last_name, :email
end
end
我试图让 "value" 是动态的,无论它是简单的布尔值 (0,1)、字符串 ('speedy') 还是序列化的项目数组 ('-- -- 棒球-橄榄球')
是否可以搜索所有 children 的用户(例如 'has_children' 设置为 'yes')?
例如:/users?fq[has_children]=yes
此外,是否可以搜索具有 children 的所有用户(例如 'number_of_children' 大于 0)?
如果是这样,您将如何构建用户模型中的 'searchable' 块和 User.search 块?
做你想做的事情的最简单方法是首先分离出你想要的不同类型的动态字段(字符串、整数、布尔值),也许通过添加 attribute_type:'string', attribute_type: 'numerical', 等等 然后你可以使用Sunspot的动态字段来搜索不同类型的动态数据:
searchable do
dynamic_string :string_attributes do
user_custom_string_attributes.inject({}) do |hash, uca|
hash.merge(uca.custom_attribute.name.to_sym => uca.value)
end
end
dynamic_integer :numerical_attributes do
user_custom_numerical_attributes.inject({}) do |hash, nuca|
hash.merge(nuca.custom_attribute.name.to_sym => nuca.value.to_i) # just making sure it's an integer!
end
end
end
# Separate out the different types of attributes for different dynamic blocks
# via methods like the one below.
def user_custom_numerical_attributes
user_custom_attributes.where(attribute_type: 'numerical')
end
def user_custom_string_attributes
user_custom_attributes.where(attribute_type: 'string')
end
这将为您提供可搜索的 'string_attributes' 对象,这些对象看起来像 {:has_children => 'no'} 或 'numerical_attributes' 像 {:number_of_children => 2}.
然后你可以像这样用一个块搜索:
User.search do
dynamic :string_attributes do
with(:has_children, 'no')
end
dynamic :numerical_attributes do
with(:number_of_children).greater_than(0)
end
end
您可以为除文本之外的几乎任何数据类型创建动态字段;为此,您必须改用字符串。一旦设置了动态字段,在 dynamic :field_name do
块内,您可以使用 Sunspot readme.