我想将搜索后过滤添加到电子商务搜索功能中。目前数据存在如下:
产品(带BrandID) 品牌(产品表中BrandID的外键) ProductDietType(产品和饮食类型的联结表) DietTypes(各种产品饮食类型) 产品部门(产品和部门的联结表) 部门
我想添加搜索后过滤器,用户可以选择多个品牌,部门,饮食类型来缩小结果集。
我能想到的就是像这样编码:
if(none)...... 如果(品牌)...... 如果(部门)...... 如果(饮食类型)...... 如果(品牌和部门)...... if(品牌和饮食类型)...... if(部门和饮食类型)...... 如果(品牌和部门和饮食类型)......
我知道这是错的。因为它不是非常可扩展的:每次添加新的过滤器时,你都会增加一倍的代码分支数。
如何整齐且可扩展地编码 - 如果我想添加另一个过滤器 - 例如原产国 - 我可以相对无痛地这样做。
我在C#中编码并使用SQL Server 2008。
任何帮助都非常感激。
乔恩
答案 0 :(得分:1)
您可以对产品属性使用通用方法。所有可能的过滤条件都称为属性(例如"部门#1和#34;),按属性类型分组(例如"部门")。
这样的模型有利有弊。例如:当品牌只是其中一个属性时,如何保证产品属于一个品牌?这是该模型的消极方面。最积极的方面是:无论你谈论的是产品的品牌,饮食类型,部门或其他什么,它们同样只是产品而且无关紧要。您可以过滤的属性。添加更多属性很容易,无需更改过滤器代码。
表attribute_type
id | text 1 | 'Brand' 2 | 'Diet type' 3 | 'Department'
表格属性
id | id_attribute_type | text 1 | 1 | 'The Salad Makers' 2 | 1 | 'Gorgeous Food' 3 | 1 | 'Great Meals' 4 | 2 | 'No fat' 5 | 2 | 'Low carb' 6 | 2 | 'No lactose' 7 | 3 | 'Department 1' 8 | 4 | 'Department 2'
表product_attribute
id_product | id_attribute 1 | 1 1 | 4 1 | 5 1 | 7 2 | 2 2 | 4 2 | 6 2 | 7
假设您选择标题中带有绿色字样的所有产品:
select * from products where upper(name) like '%GREEN%';
此外,您需要与所选产品相关联的所有过滤器:
select at.id as at_id, at.text as at_text, a.id as a_id, a.text as a_text
from product_attribute pa
join attribute a on a.id = pa.id_attribute
join attribute_type at on at.id = a.id_attribute_type
where pa.id_product in (select id from products where upper(name) like '%GREEN%');
如果' GREEN'产品恰好是产品1和产品2然后得到:
现在用户选择Brand =' The Salad Makers'和'饮食类型' ='没有脂肪'或者'没有乳糖'。这使得:
select *
from products
where upper(name) like '%GREEN%'
and id in
(
select id_product
from product_attribute
group by id_product
having sum(case when id_attribute in (1) then 1 end) > 0 criteria for Brand
and sum(case when id_attribute in (4,6) then 1 end) > 0 -- criteria for Diet type
);
您只需在每个使用的属性类型(此处为1个品牌和2个饮食类型)中添加一个条件行,并使用包含所选属性的IN子句来创建此类查询。
这样的模型可以变得更加复杂。例如,可能会有一些与OR相关的过滤器(品牌x 或 y的所有产品)和其他带AND的过滤器(所有产品都是甜的和酸)。
嗯,你明白了。我不知道你是否认为这适合你正在做的事情。这只是一个想法。如上所述,它有优点,但它也有缺点。
您可能还会决定混合概念(例如:品牌等主要属性保留实际列,而其他属性则转到属性表)。