具有多过滤器的应用程序的理想数据建模是什么?

What's the ideal data modeling for app with multi-filters?

查看了 Firestore 文档 + Google 的 I/O 2019 网络研讨会,但我仍然不清楚适合我的特定用例的正确数据建模。

  1. 应用程序允许专业服务提供商在预定义的类别(住宿、运动、健康...)中以预定义的价格点(50 美元、75 美元、100 美元)注册和发布他们的一项或多项服务...).
  2. 主页上的用户将首先使用价格点滑块进行过滤 - 参见线框),例如:199 欧元,然后 可选 通过选择类别,例如:所有'Sports'(199 欧元)和地点(例如:英国的所有运动项目 199 欧元)。 可选,因为用户还可以在选择价格后立即使用按钮构建他们的列表。同样的 'build list' 按钮在类别选择之后和位置选择之后。所以3个过滤深度是可能的。

什么是理想的数据结构,因为我想在每次过滤时避免数千次读取。 三个根级集合(服务提供商、价格点、服务类别?)及其相关文件?我理解并接受非规范化用于我的过滤。

为了更好地理解过滤,下面是线框图:

App lets pro service providers register and publish one or more of their services in pre-defined categories (Stay, Sports, Wellness...) and at pre-defined price points (50$, 75$, 100$...).

由于您有 pre-defined 类别、价格和位置,因此对此类数据库建模的最简单解决方案是拥有一个产品集合:

Firestore-root
  |
  --- products (collection)
        |
        --- $productId (document)
               |
               --- name: "Running Shoe"
               |
               --- category: "Sport"
               |
               --- price: 199
               |
               --- location: "Europe"
               |
               --- country: "France"

通过这种方式,您可以简单地执行您需要的所有查询。由于您没有指定编程语言,我将在 Java 中编写查询,但您可以简单地将它们转换为任何其他编程语言。因此,例如,您可以查询具有特定价格的所有产品:

FirebaseFirestore db = FirebaseFirestore.getInstance();
Query queryByPrice = db.collection("products").whereEqualTo("price", 199);

如果需要按价格、品类、位置查询,则需要串联多个whereEqualTo()方法:

Query queryByPrice = db.collection("products")
                       .whereEqualTo("price", 199)
                       .whereEqualTo("category", "Sport")
                       .whereEqualTo("location", "Europe");

但是,如果您需要对结果进行升序或降序排序,请不要忘记创建一个

What would be the ideal data structure, given that I want to avoid thousands of reads each time there's filtering.

如果您不需要一次获得所有结果,那么您必须实现分页。如果您需要提前知道运动类别中存在的产品数量,那么如果不执行查询并计算可用产品数量,这是不可能的。我写了一篇关于这个主题的文章,名为:

另一个可行的解决方案是创建一个包含所有这些数字的文档。换句话说,就是您向用户显示的内容,这些屏幕截图中存在的所有内容。这样,您只需支付一次读取操作的费用。当用户单击特定类别时,您才应该执行实际搜索。

I understand and accept denormalization for the purpose of my filtering.

在这种情况下,不需要对数据进行反规范化。有关此类操作的更多信息,请在下面查看我的回答: