MySQL实现基于多过滤器的搜索
从下面的表结构中,我希望能够提供基于属性组合的搜索过滤器: 表格:动物纪念品MySQL实现基于多过滤器的搜索,mysql,sql,search,filtering,Mysql,Sql,Search,Filtering,从下面的表结构中,我希望能够提供基于属性组合的搜索过滤器: 表格:动物纪念品 id attributeId animalId 1 455 55 2 999 55 3 685 55 4 999 89 5 455 89 6 333 93 7 685
id attributeId animalId
1 455 55
2 999 55
3 685 55
4 999 89
5 455 89
6 333 93
7 685 93
8 999 93
--------------------------------
attributeId attributeCategoryId attribute
233 1 Fur
333 1 Scales
455 1 Feathers
685 2 Black
999 2 Brown
-----------------------------------------------
attributeCategoryId category
1 Body covering
2 Colour
------------------------------------
前端会有复选框,例如
Animal options
Colour
[ ] Black (id 685)
[x] Brown (id 999)
Body Covering
[ ] Fur (id 233)
[ ] Scales (id 333)
[x] Feathers (id 455)
我希望上面的复选框选择所有棕色和有羽毛的动物。我可以通过以下查询获取此数据:
SELECT animalId
FROM animalAttributes
WHERE attributeId IN (999,455)
GROUP BY animalId
HAVING COUNT(DISTINCT attributeId) = 2;
SELECT animalId
FROM animalAttributes
WHERE
attributeId IN (685,233) ||
attributeId IN (685,455) ||
attributeId IN (999,233) ||
attributeId IN (999,455)
GROUP BY animalId
HAVING COUNT(DISTINCT attributeId) = 2;
我遇到的问题是当从多个过滤器中选择多个选项时,例如
Animal options
Colour
[x] Black (id 685)
[x] Brown (id 999)
Body Covering
[x] Fur (id 233)
[ ] Scales (id 333)
[x] Feathers (id 455)
我希望上面的复选框选择所有的动物(黑色或棕色)和有(毛发或羽毛)。我可以通过以下查询获取此数据:
SELECT animalId
FROM animalAttributes
WHERE attributeId IN (999,455)
GROUP BY animalId
HAVING COUNT(DISTINCT attributeId) = 2;
SELECT animalId
FROM animalAttributes
WHERE
attributeId IN (685,233) ||
attributeId IN (685,455) ||
attributeId IN (999,233) ||
attributeId IN (999,455)
GROUP BY animalId
HAVING COUNT(DISTINCT attributeId) = 2;
如果我想添加额外的过滤器,如“Has Tail”、“Can fly”、“Blood type”等,我是否正确地认为我需要计算所有组合()并遵循与上面相同的模式?e、 g.5个过滤器,每个过滤器选择1个或多个选项
attributeId IN (x,x,x,x,x) ||
attributeId IN (x,x,x,x,x) ||
attributeId IN (x,x,x,x,x) ||
...
HAVING COUNT(DISTINCT attributeId) = 5;
其他参考表格
表格:属性
id attributeId animalId
1 455 55
2 999 55
3 685 55
4 999 89
5 455 89
6 333 93
7 685 93
8 999 93
--------------------------------
attributeId attributeCategoryId attribute
233 1 Fur
333 1 Scales
455 1 Feathers
685 2 Black
999 2 Brown
-----------------------------------------------
attributeCategoryId category
1 Body covering
2 Colour
------------------------------------
表格:属性类别
id attributeId animalId
1 455 55
2 999 55
3 685 55
4 999 89
5 455 89
6 333 93
7 685 93
8 999 93
--------------------------------
attributeId attributeCategoryId attribute
233 1 Fur
333 1 Scales
455 1 Feathers
685 2 Black
999 2 Brown
-----------------------------------------------
attributeCategoryId category
1 Body covering
2 Colour
------------------------------------
将与您所写的内容相同:
属性ID IN(68523345599233)
尝试:
或者说:
(黑色或棕色和浅色)和(毛皮或羽毛和身体覆盖物)
取消测试,但您应该了解这一点。您也可以通过交叉口执行此操作。您可以编写一个查询,为每个筛选器生成一个结果集。然后,您可以将所有结果集相交,得到一个适合所有过滤器的结果集
这种方法的缺点是在数据库上执行多个查询。如果性能是一个问题,因为你的应用程序有很多流量,你可以做一些内存密集型而不是进程密集型的事情,比如缓存你正在查询的数据库表,这样你只需要对数据库进行一次调用。如果我正确理解你的问题,按位键可能会有所帮助。例如,假设每只动物都有多个二进制选项。例如has tail=是或否(0或1),has Scales、has Fir等的情况相同 然后,通过将所有可能的属性添加为一组二进制选项,您就可以 尾(Y/N)冷杉(Y/N)鳞片(Y/N)棕色(Y/N) 01101 也就是说,这种动物没有尾巴,有冷杉,没有鳞片,是棕色的
使用此键可以轻松筛选与该条件匹配的所有项目,并且可以添加新的条件,而无需对查询进行额外的代码更改。请查看使用这些键的按位运算符。但一般来说,您是如何做到这一点的?如果您添加了另一个类别,那么您必须重写您的查询。必须有一个查询,允许在不更改查询的情况下添加新属性数据。如果您使用新房间扩建房屋,您将不得不在旧房子中建一扇门。
a.attributeCategoryId
不太可能同时是1
和2
。实际上,现在看起来您几乎成功了。您可能只需将'main'和
,即,WHERE(…)**和**(…)
,更改为或
,并添加HAVING COUNT(DISTINCT a.attributeCategoryId)=2
。拥有一些测试数据和预期的查询输出将非常有用,这样我们就可以尝试各种查询,直到得到正确的答案。