2009-10-15 8 views
1

С этими ассоциациями только результаты увеличения возвращают правильные результаты, но когда я попытаюсь найти вторую ассоциацию, она вернет 0 результатов.Как искать различные условия из одной таблицы соединений?

has_one :magnification, 
    :class_name => 'ProductAttribute', 
    :foreign_key => 'product_id', 
    :conditions => {:key => 'Magnification'} 
has_one :objective_lens, 
    :class_name => 'ProductAttribute', 
    :foreign_key => 'product_id', 
    :conditions => {:key => 'Objective Lens Diameter'} 

define_index do 
    has magnification(:value), :type => :float, :as => :magnification 
    has objective_lens(:value), :type => :float, :as => :objective_lens_diameter 
end 

Пример кода Используется

# returns expected results 
Product.search(nil, :with => {:magnification => (8.0..9.0)}) 

# returns 0 results 
Product.search(nil, :with => {:objective_lens_diameter => (31.0..61.0)}) 

Но когда я обратный порядок define_index наоборот происходит. Таким образом, результаты объективного диаметра линзы возвращают правильные результаты и возвращает увеличение приводит 0.

Использования Rails v2.2, мышление-Sphinx как плагин v1.2.12 и Сфинкс 0.9.8

Edit: Глядя при генерируемом значении sql_query показано, что соединение 2-го атрибута использует неправильные ассоциации, чтобы оно не возвращало ожидаемые результаты.

упрощенный результаты:

SELECT 
    `products`.`id` * 2 + 1 AS `id`, 
    `products`.`id` AS `sphinx_internal_id`, 
    1234567890 AS `class_crc`, 
    `product_attributes`.`value` AS `magnification`, 
    `objective_lens_products`.`value` AS `objective_lens_diameter` 
FROM `products` 
    LEFT OUTER JOIN `product_attributes` ON product_attributes.product_id = products.id 
    AND `product_attributes`.`key` = 'Magnification' 
    LEFT OUTER JOIN `product_attributes` objective_lens_products ON objective_lens_products.product_id = products.id 
    AND `product_attributes`.`key` = 'Objective Lens Diameter' 
WHERE `products`.`id` >= $start 
    AND `products`.`id` <= $end 
GROUP BY `products`.`id` 
ORDER BY NULL 
+0

Этот SQL является вашей проблемой. Он соединяет атрибуты продукта с продуктами дважды, как и должно. Но он использует неправильное соединение при сопоставлении ключа с Objective Lens Diameter. Опять же, я чувствую, что это связано с тем, как вы определили свои ассоциации. – EmFi

+0

SQL, который генерируется, происходит из плагина Thinking Sphinx, как я уже отмечал выше, когда добавлял его в сообщение, что он был источником проблемы. Нет ничего плохого в том, как были построены ассоциации. – Vizjerai

ответ

1

Вы можете поделиться sql_query, сгенерированными для вашей модели изделий внутри, development.sphinx.conf? На самом деле, то, что вы делаете, должно работать для обоих атрибутов, так что это может быть ошибка в сгенерированной команде SQL.

+0

Я добавил созданный запрос, удалив ненужные части, и похоже, что сгенерированный SQL не был создан, как ожидалось. – Vizjerai

+0

@Pat, я все еще сталкиваюсь с этой проблемой. Вы исправили эту проблему? – Anikethana

+0

@Anikethana Прошло несколько лет с тех пор, как эта тема была активной. Какую версию Thinking Sphinx вы используете? – pat

0

сфинкс материал в основном правильно. Нил в поисках лишний. Но я, честно говоря, не думаю, что это вызывает твою проблему.

Я думаю, что ваша проблема связана с вашими отношениями модели. В частности, ваша взломанная версия Single-Inheritance (STI) и способ, которым Sphinx обрабатывает индексы.

Похоже, вы пытаетесь дублировать индекс, чтобы он игнорировал второй.

Я не совсем уверен, как это исправить, добавив, что запросы к блоку define_index не работают, потому что все утверждения where применяются ко всем индексам, определенным впоследствии, и не могут быть написаны, только добавлены. Мышление sphinx также плохо работает с несколькими индексами на модели, поэтому вы не можете исправить это, переопределив блок define_index.

Thinking-Sphinx 1.2 предоставляет Sphinx Scopes, что вы можете захотеть найти в качестве потенциального решения. К сожалению, это плохо документировано, поэтому я не могу сказать, будет ли это работать или нет.

Учитывая отсутствие хитов в отношении гуглингов STI-Sphinx STI и «Single Inheritance Table». Я ожидаю переопределения ваших отношений, позволяя рельсам обрабатывать ИППП, чтобы решить ваши проблемы.

Она включает в себя делать что-то вроде этого:

class ProductAttribute < ActiveRecord::Base 
    belongs_to :product 
    inheritance_column => :key 
    ... 
    common methods and validations to objective\_lens\_diameters and and magnifications 
    ... 
end 

class Magnification < ProductAttribute 
    ... 
    methods and validations unique to magnifications. 
    ... 
end 

class ObjectLensDiameter < ProductAttribute 
    ... 
    methods and validations unique to object lens diameters 
    ... 
end 

class Product < ActiveRecord::Base 
    has_one :magnification 
    has_one :objective_lens 

    define_index do 
    has magnification(:value), :type => :float, :as => :magnification 
    has objective_lens(:value), :type => :float, :as => :objective_lens_diameter 
    end 
end 

Вам может понадобиться для миграции, чтобы привести существующие ключевые значения в таблице ProductAttributes рядный с тем, что STI ожидает, что они будут.

+0

Нуль в поиске заключался в том, чтобы упростить код и отправленные нильсы вернули все результаты. Мне было бы хорошо с использованием has_many: product_attributes, если бы я смог настроить таргетинг на определенные атрибуты для фильтрации по этим атрибутам. – Vizjerai

0

Я решил работать до тех пор, пока ассоциации sql_query не будут исправлены. Производительность хуже, чем использование левых объединений, но в то же время уменьшает объем внешнего кода, необходимый для его работы.

Таким образом, индекс определения был изменен для использования фрагмента SQL, чтобы получить конкретный столбец напрямую, а не полагаться на какие-либо соединения.

define_index do 
    has "(SELECT `value` " + 
    "FROM `product_attributes` " + 
    "WHERE `product_id` = `products`.`id` " + 
    " AND `key` = 'Magnification' " + 
    "LIMIT 0, 1)", 
    :type => :float, 
    :as => :magnification 
    has "(SELECT `value` " + 
    "FROM `product_attributes` " + 
    "WHERE `product_id` = `products`.`id` " + 
    " AND `key` = 'Objective Lens Diameter' " + 
    "LIMIT 0, 1)", 
    :type => :float, 
    :as => :objective_lens_diameter 
end 

Сформирован sql_query

SELECT `products`.`id` * 2 + 1 AS `id`, 
    `products`.`id` AS `sphinx_internal_id`, 
    123456789 AS `class_crc`, 
    IFNULL('987654321', 0) AS `subclass_crcs`, 
    0 AS `sphinx_deleted`, 
    (SELECT `value` 
    FROM `product_attributes` 
    WHERE `product_id` = `products`.`id` 
     AND `key` = 'Magnification' 
    LIMIT 0, 1) AS `magnification`, 
    (SELECT `value` 
    FROM `product_attributes` 
    WHERE `product_id` = `products`.`id` 
     AND `key` = 'Objective Lens Diameter' 
    LIMIT 0, 1) AS `objective_lens_diameter` 
FROM `products` 
WHERE `products`.`id` >= $start 
    AND `products`.`id` <= $end 
GROUP BY `products`.`id` 
ORDER BY NULL 
0

Я установил его, используя короткий метод обреза, не уверен, что это хорошо или нет ... Я определил третье соотношение, которые включают как те отношения, которые я ранее определенные только для поиска и использования этого метода define_index. Вы можете видеть мои отношения здесь - http://stackoverflow.com/questions/15791007/thinking-sphinx-search-for-different-conditions-from-the-same-join-table/15804611#15804611