图 5-15 笔记本电脑商品筛选器


    比如对于图 5-15 展示的笔记本电脑筛选器来说,如果我们点击图中“品牌”一栏的“ThinkPad”图标,那么筛选器将只在页面里展示 ThinkPad 品牌的笔记本电脑。如果我们继续点击“尺寸”一栏中的“13.3英寸”选项,那么筛选器将只在页面里展示 ThinkPad 品牌的 13.3 英寸笔记本电脑,诸如此类。

    实现商品筛选器的其中一种方法是使用反向索引,这种数据结构可以为每个物品添加多个关键字,然后根据关键字去反向地获取相应的物品。举个例子,对于 这台笔记本电脑来说,我们可以为它添加 "ThinkPad""14inch""Windows" 等关键字,然后通过这些关键字来反向获取 这台电脑。

    实现反向索引的关键是要在物品和关键字之间构建起双向的映射关系,比如对于刚刚提到的 "X1 Carbon" 电脑来说,反向索引程序需要构建出图 5-16 所示的两种映射关系:

    • 第一种映射关系将 "X1 Carbon" 映射至它带有的各个关键字;


    图 5-16 X1 Carbon 电脑及其关键字的映射关系_images/IMAGE_X1_INDEX_1.png


    代码清单 5-9 展示了一个使用集合实现的反向索引程序,对于用户给定的每一件物品,这个程序都会使用一个集合去储存物品带有的多个关键字;与此同时,对于这件物品的每一个关键字,程序都会使用一个集合去储存关键字与物品之间的映射。因为构建反向索引所需的这两种映射都是一对多映射,所以使用集合来储存这两种映射关系的做法是可行的。


    代码清单 5-9 反向索引程序:/set/inverted_index.py


    为了测试这个反向索引程序,我们在以下代码中,把一些笔记本电脑产品的名称及其关键字添加到了反向索引里面:

    1. >>> from redis import Redis
    2. >>> from inverted_index import InvertedIndex
    3. >>> client = Redis(decode_responses=True)
    4. >>> laptops = InvertedIndex(client)
    5. 3
    6. >>> laptops.add_index("MacBook Air", "Apple", "MacOS", "13inch")
    7. 3
    8. >>> laptops.add_index("X1 Carbon", "ThinkPad", "Windows", "13inch")
    9. 3
    10. >>> laptops.add_index("T450", "ThinkPad", "Windows", "14inch")
    11. >>> laptops.add_index("XPS", "DELL", "Windows", "13inch")
    12. 3

    在此之后,我们可以通过以下语句来找出 电脑带有的所有关键字:

    1. >>> laptops.get_items("13inch")
    2. set(['MacBook Pro', 'X1 Carbon', 'MacBook Air', 'XPS'])

    还可以使用以下语句来找出所有屏幕大小为 13 英寸并且使用 Windows 系统的笔记本电脑:

    或者使用以下语句来找出所有屏幕大小为 13 英寸并且使用 Windows 系统的 ThinkPad 品牌笔记本电脑:

    1. >>> laptops.get_items("13inch", "Windows", "ThinkPad")
    2. set(['X1 Carbon'])

    图 5-17 展示了以上代码在数据库中为物品创建的各个集合,而图 5-18 则展示了以上代码在数据库中为关键字创建的各个集合。


    图 5-17 反向索引程序为物品创建的集合_images/IMAGE_II_ITEM_INDEX.png


    图 5-18 反向索引程序为关键字创建的集合