如何使用聚合在 Elasticsearch 中实现层次分面搜索

Kar*_*ski 7 php mysql elasticsearch

我正在开发一个标准的电子商务应用程序,该应用程序包含多对多类别的产品。

类别是树并以嵌套集形式存储在数据库中。

类别可以有子类别等等。

我想将 Elasticsearch 用于搜索功能,但我找不到任何用于此类标准(几乎所有网上商店都具有该功能)分面搜索的用例(或示例),我将在下面尝试解释:

类别

桌子:

----------------------------------------------
|id      | name        | lft     | rgt       |
----------------------------------------------
|1       | Electronics | 1       | 18        |
|2       | Accesories  | 2       | 9         |
|3       | Cards       | 3       | 4         |
|4       | Stations    | 5       | 6         |
|5       | Cables      | 7       | 8         |
|6       | Computers   | 10      | 15        |
|7       | Laptops     | 11      | 12        |
|8       | Software    | 13      | 14        |
|9       | Phones      | 16      | 17        |
|10      | House       | 19      | 20        |
Run Code Online (Sandbox Code Playgroud)

视觉上:

Electronics
    Accesories
        Cards
        Stations
        Cables
    Computers
        Laptops
        Software
    Phones
House
Run Code Online (Sandbox Code Playgroud)

产品

---------------------------
|id      | name           |
---------------------------
|1       | Lenovo G580    |
|2       | Iphone 5       |
|3       | Keyboard       |
|4       | Mouse          |
|5       | Sony Xperia Z5 |
Run Code Online (Sandbox Code Playgroud)

产品和类别

---------------------------
|product_id  | category_id |
----------------------------
| 1          | 1           |
| 1          | 6           |
| 1          | 7           |
| 2          | 1           |
| 2          | 9           |
| 3          | 1           |
| 3          | 2           |
| 4          | 1           |
| 4          | 2           |
| 5          | 1           |
| 5          | 9           |
Run Code Online (Sandbox Code Playgroud)

我想做的事

情况1

假设在这种情况下没有选择类别并且搜索框输入为空。我想显示属于所有根类别的不同产品,并在所有这些类别中进行计数。有这样的想法:

-----------------------------------------------------------------
| ------------------------------------                          |
| | type for searching...            |                          |
| ------------------------------------                          |
-----------------------------------------------------------------
| Categories       | Products                                   |
-----------------------------------------------------------------
| Electronics (5)  | |-------------------------------------------
|                  | |  Lenovo G580                             |
|                  | |-------------------------------------------
|                  | |-------------------------------------------
|                  | |  Iphone 5                                |
|                  | |-------------------------------------------
|                  | |-------------------------------------------
|                  | |  Keyboard                                |
|                  | |-------------------------------------------
|                  | |-------------------------------------------
|                  | |  Mouse                                   |
|                  | |-------------------------------------------
|                  | |-------------------------------------------
|                  | |  Sony Xperia Z5                          |
|                  | |-------------------------------------------
Run Code Online (Sandbox Code Playgroud)

请注意,左侧没有房屋类别,因为它没有产品。

案例二

假设在这种情况下选择了一个类别并且搜索框输入再次为空。

对我来说有一个关键点:

如果用户选择类别(在本例中为电子产品),我想显示其子类别的一个级别,其中包含属于其父类别链接的产品数量。有这样的想法:

-----------------------------------------------------------------
| ------------------------------------                          |
| | type for searching...            |                          |
| ------------------------------------                          |
-----------------------------------------------------------------
| Categories       | Products                                   |
-----------------------------------------------------------------
| ^--              | |-------------------------------------------
| Accesories (2)   | |  Lenovo G580                             |
| Computers (1)    | |-------------------------------------------
| Phones (2)       | |-------------------------------------------
|                  | |  Iphone 5                                |
|                  | |-------------------------------------------
|                  | |-------------------------------------------
|                  | |  Keyboard                                |
|                  | |-------------------------------------------
|                  | |-------------------------------------------
|                  | |  Mouse                                   |
|                  | |-------------------------------------------
|                  | |-------------------------------------------
|                  | |  Sony Xperia Z5                          |
|                  | |-------------------------------------------
Run Code Online (Sandbox Code Playgroud)

案例3

如果用户选择最后一个类别级别(如下面的电话),我只想显示该级别和该产品

-----------------------------------------------------------------
| ------------------------------------                          |
| | type for searching...            |                          |
| ------------------------------------                          |
-----------------------------------------------------------------
| Categories       | Products                                   |
-----------------------------------------------------------------
| ^--              | |-------------------------------------------
| Phones (2)       | |  Iphone 5                                |
|                  | |-------------------------------------------
|                  | |-------------------------------------------
|                  | |  Sony Xperia Z5                          |
|                  | |-------------------------------------------
Run Code Online (Sandbox Code Playgroud)

案例四

如果用户在搜索框中输入 somethink(但不选择任何类别),我想显示所有具有匹配搜索条件的产品以及与该产品匹配的所有独特类别(无论在哪个级别)。

抱歉问了这么长的问题,但我希望它能解释我的意思。

如何使用 Elasticsearch 实现这种标准方式?

研究

SearchKit http://demo.searchkit.co/以其http://docs.searchkit.co/stable/docs/components/navigation/hierarchical-menu.html 的方式工作,但我不知道如何映射并应实施查询以实现这种情况......