7

我有一个 Firebase 数据库。我有 Job 对象和 Item 对象。每个 Job 可以包含多个 Item,一个 Item 必须包含在一个 Job 中(简单的一对多)。我目前的数据库结构是 Item 和 Job 都是 firebase 中的顶级列表,每个 Item 都包含它所属的 jobKey。只要我知道作业密钥,这使我可以找到作业中的所有项目。用于查找项目的 firebase 代码需要一个查询,其中包括项目中的 jobKey 和一个“orderBy”。因此,很容易检索作业的所有项目。但是,我还想根据项目中的附加数据对项目进行排序和过滤。但是由于单个“orderBy”的firebase限制,我无法使用firebase完成第二级过滤。这是我的挑战。我目前的数据结构如下图所示。

+--jobs
  |
  +-- jobKey1
  |  |
  |  +-- <jobdata1> ..
  |  
  +-- jobKey2
     |
     +-- <jobdata2>..

+--items
  |
  +-- itemKey1
  |  |
  |  +-- jobKey : jobKey2  // this item belongs to job2
  |  |
  |  +-- <the rest of item1 data
  |  
  +-- itemKey2
  |  |
  |  +-- jobKey : jobKey2  // this item belongs to job2
  |  |
  |  +-- <the rest of item2 data
  |  
  +-- itemKey3
  |  |
  |  +-- jobKey : jobKey1  // this item belongs to job1
  |  |
  |  +-- <the rest of item3 data
  |  
  +-- itemKey4
     |
     +-- jobKey : jobKey1  // this item belongs to job1
     |
     +-- <the rest of item4 data

如前所述,我希望能够检索作业的所有项目,然后按项目中的各个字段对项目进行排序和过滤。鉴于上面的结构,这样做的唯一方法(我看到)是使用 firebase 查询来检索项目,然后使用组件中的逻辑(我正在使用 angular2)将所有项目缓存到某种集合中然后根据缓存的数据进行排序和过滤。这不是很令人满意,必须有更好的方法。有哪些合理的替代方案?

4

1 回答 1

11

我已经想出了解决方案。

构造数据的另一种方法是将项目列表直接嵌套在作业中。如下图所示。这允许使用 firebase 查询在项目数据中排序和过滤。这似乎是一个很好的解决方案,但它具有扩展缺陷。

   +--jobs
      |
      +-- jobKey1
      |  |
      |  +-- <jobdata> ..
      |  |
      |  +-- items
      |     |
      |     +-- itemKey3
      |     |  |
      |     |  +-- <the rest of item3 data>
      |     | 
      |     +-- itemKey4
      |        |
      |        +-- <the rest of item4 data> 
      |  
      +-- jobKey2
         |
         +-- <jobdata>..
         |
         +-- items
            |
            +-- itemKey1
            |  |
            |  +-- <the rest of item1 data>
            | 
            +-- itemKey2
               |
               +-- <the rest of item2 data> 

这个解决方案的一个缺点是,如果项目列表很大,它的扩展性就不是很好,因为每次读取 Job 都会读取所有项目。就我而言,当我阅读 Job 对象时,我不想阅读整个项目列表,而是想创建项目列表的引用并在项目列表上使用 firebase 查询/过滤功能。因此,将项目列表放在 Job 中确实没有直接的好处。在我的应用程序中,实际限制是数百个项目。因此,即使该解决方案可能适用于我的应用程序,也必须有一个更好、更具可扩展性的解决方案。

更好的解决方案。

经过进一步考虑,这个问题的最佳解决方案是创建特定于作业但不包含在 Job 对象中的 Item 列表,这样在读取 Job 时,不必读取整个列表。我们还保留了根据数据对项目列表中的数据进行排序/过滤的能力。这种结构如下图所示。每个作业的 ItemLists 保存在路径“itemlists/<jobKey>/items”

+--jobs
   |
   +-- jobKey1
   |  |
   |  +-- <jobdata1> ..
   |  
   +-- jobKey2
      |
      +-- <jobdata2>..

 +--itemlists
   |
   +-- jobKey1    // items list for job1   
   |  |
   |  +--items
   |    |
   |    +-- itemKey3
   |    |  |
   |    |  +-- <the rest of item3 data
   |    |  
   |    +-- itemKey4
   |    |  |
   |    |  +-- <the rest of item4 data
   |    
   +-- jobKey2    // items list for job2   
      |
      +--items
        |
        +-- itemKey1
        |  |
        |  +-- <the rest of item1 data
        |  
        +-- itemKey2
           |
           +-- <the rest of item2 data
于 2016-07-28T16:56:44.800 回答