mysql 执行查询后,更新UI中的筛选器选项

pxq42qpu  于 2023-02-18  发布在  Mysql
关注(0)|答案(2)|浏览(118)

bounty将在11小时后过期。回答此问题可获得+50的声望奖励。reddfox正在寻找规范答案

我正在为一个客户构建一个Web应用程序,该客户的MySQL数据库中有约1M行数据。数据大致如下所示:
产品

+---------+-----------+---------+-------------+---------+----------+
| Id      | Name      | Size    | Colour      | 4 Other attributes |
+---------+-----------+---------+-------------+---------+----------+
|    1    | product 1 |  S,M,L  | red, green  | ... other options  |
|    2    | product 2 |  XL     | blue, green | ... other options  |
| ................................................................ |

在我的应用程序的产品页面上,有:

  • 包含筛选器的边栏列(来自上述属性的6个筛选器组及其各自的选项)
  • 用户查看产品结果的主要区域(分页时一次50个)

当用户点击过滤器选项(例如,颜色=蓝色)时,I查询以更新主区域中的结果(例如,颜色=蓝色的所有产品)。
我可以执行什么查询来获取其他筛选器组的其余筛选器选项?
例如,如果用户选择colour=blue,这将减少其他滤镜组中的选项数量,例如size(如果您查看上面的示例数据,则将保留的唯一size选项将是XL)。
我无法从colour=blue查询的所有结果中获取过滤器选项,因为有100k以上的结果,而我一次只能获取50个。
步骤1:所有选项可用。

Sizes
[ ] S
[ ] M
[ ] L
[ ] XL

Colours
[ ] red
[ ] green
[ ] blue

第2步:用户选择“蓝色”,更新尺寸选项。

Sizes
[ ] XL

Colours
[ ] red
[ ] green
[x] blue

下面是另一个网站做类似事情的例子。(这个网站也列出了数百万种产品。)
步骤1:初始加载,未选择筛选器。

第二步:选择其中一个过滤器选项,右边的结果会更新,侧边栏中其他过滤器组的过滤器选项也会更新。

nimxete2

nimxete21#

    • 问题**"我可以执行什么查询来获取其他筛选器组的其余筛选器选项?"
    • 简短回答**

使用暴力查询来获取数据并计算结果。

    • 详细答案**

下面是一些需要做的事情的提示。它提供了一些关于提高性能的建议。
1.将产品分成大约100个不同的组(CD、服装、相机、汽车零件等),这将(1)成为PRIMARY KEY的第一列,(2)限制随后的大量查询。
1.研究数据,找出相关的分组(价格、尺寸、颜色、光圈值等)。确保定期重新研究数据。如果RAM芯片从1MB开始,到256MB停止,那会显得很愚蠢。要知道,像"尺寸"这样的词对T恤和磁盘驱动器有不同的含义,对单一尺寸的东西没有意义。
1.每当选中(或取消选中)筛选框时,就会强制搜索整个组。
1.将数据拆分成2个表(以及许多辅助表)。一个表只包含被认为值得过滤的列。一个表包含所有其他信息(描述、图像的URL等)。第一个表将用于搜索和重建分组。
1.跟踪人们过滤的东西。(谁在乎RAM芯片的颜色!)用这个来消除无用的过滤器。这将很难发现新的过滤器(例如,当磁盘驱动器添加"SSD"选项)。
1.请注意,用户会希望在每个过滤器中选中多个复选框。(例如,2个价格范围或2个尺寸)
1.一定要仔细计划"分页";这可能是性能杀手。
1.对于过滤,不要"标准化"。那会使"XL"保持为"XL"而不是一个数字。然而,你可能需要一个数字来以一种合理的方式对选项进行排序(XS〈S〈M〈L〈XL)。一定要使数字保持为数字(例如,兆字节),这样它们就可以很容易地被扔到桶里。
性能不会很好。但是我建议了一些事情来避免大的表扫描:

  • 强制用户从严格限制要扫描的数据量的分组开始。
  • 对它进行适当的索引,以便扫描"连续的"行。
  • 垂直分割--搜索值与其余内容。

"也许..."
计数(页面左侧)

SELECT  COUNT(*) AS total,
        SUM(genre = 'Hip Hop') AS "Hip Hop",
        ...
    FROM search_table
    WHERE category = 'CD'
      AND artist = '...'   -- already picked items

显示前20个(页面的主要部分)

SELECT  i.*
    FROM search_table AS s
    JOIN info AS i  ON s.id = s.id
    WHERE s.category = 'CD'
      AND s.artist = '...'   -- already picked items
    ORDER BY s.price ASC     -- user-chosen sort order
    LIMIT 0, 20              -- for pagination

然而,这是复杂的,因为CD不需要/想要一个列color,大多数其他项目也不需要一个列genre

  • 100个搜索表(每个类别一个),每个表具有适当的搜索类别作为列(具有适当的数据类型)。
PRIMARY KEY (price, id),
  INDEX(id)
  • JSON字符串中包含大多数搜索条件的单个表。
PRIMARY KEY (category, price, id),
  INDEX(id)

注:

  • 在这两种方法中,可能都有price的列,假设 * 大多数 * 类别需要这样的过滤器。
  • 在这两种方法中,按表或按PK过滤都将把搜索缩小到大约1/100的行。

第三种选择是PARTITION BY KEY或LIST,并且有100个分区,也许更少;例如,不同类型的衣服可能在同一组中工作得很好。2或者媒体(CD等)或车辆(汽车、卡车)。

PRIMARY KEY(price, cat, id),  -- cat not needed first
INDEX(id)
aurhwmvo

aurhwmvo2#

若要在用户选择的颜色不具有所有大小时限制大小列表,请生成一个包含所有可能组合的筛选器查询。
返回的JSON如下所示:

{filters:[
  {
    color:green,
    size:sm
  },
  {
    color:green,
    size:md
  },
  {
    color:green,
    size:lg
  },
  {
    color:green,
    size:xl
  },
  {
    color:blue,
    size:xl
  },
  ...
]

在客户端有一个选定颜色的数组和一个选定大小的数组。当这些得到更新时,使用filterOptions重绘过滤器列表。filter(f =〉{..只给予我f,其中两个字段都存在于它们各自的过滤器数组中}),然后使用这个过滤后的数组再次过滤到相关的维度。如果您有两个以上的维度,那么它会增长得非常快,因此,如果维度因产品类型而异,那么您可能需要另一个抽象层来使过滤通用。

相关问题