使用Algolia Search时,如何为具有变体的项目构建firestore集合?

时间:2018-03-12 11:00:02

标签: google-cloud-firestore algolia react-instantsearch

因为标题暗示我在firestore中有一个项目集合,如下所示:

ParentCollection
    items
        ->docId_1
            ->name: 'Shirt'
            ->price: 5
            ->tags: ['tag1', 'tag2', 'tag3']
            ->attribute1: 'blah'
            ->attribute2: 'blahblah'

但是,我需要这些项目有变体,例如不同的尺寸/颜色/等。在这种结构中,唯一的方法是为每个变体设置一个全新的项目。哪个不理想,

这是我目前对要求的看法:

  • 包含所有变体的父项,具有唯一的docId
  • 每个变体都有一个唯一的docId,但以某种方式附加到父项
  • 常用属性是父项(名称,公司,标签等)
  • 上的字段
  • 每种变体都有独特的属性(可用,尺寸/类型,价格)

我目前的计划是:

ParentCollection

    items
        ->parentDocId_1
            ->name: 'Shirt'
            ->variants : [{
                size: S,
                available: true,
                variantDocId: variantDocId_1
                },{
                size: L,
                available: false,
                variantDocId: variantDocId_2
                }]
            ->tags: ['tag1', 'tag2', 'tag3']
            ->attribute1: 'blah'
            ->attribute2: 'blahblah'

                SubCollection
                    variants
                        ->variantDocId_1
                            ->size: 'S'
                            ->price: 5
                            ->parentDocId: parentDocId_1
                        ->variantDocId_2
                            ->size: 'L'
                            ->price: 10
                            ->parentDocId: parentDocId_1

我可以看到一些问题。

  1. 由于Firestore在请求父集合时无法获取子集合,因此需要额外的数据库调用。

  2. 一个很大的问题是我需要为项目附加一个可用属性,之前我已经在项目集合级别中使用了它,但是现在我有变种我需要将它放在每个变体上。如果我在父集合级别的variants数组中有它,我认为我不能再过滤algolia搜索中的可用,因为一个Item会有多个值。如果我在变体子集合中提供了down,那么algolia没有将其编入索引,因为它只是Items集合中的索引文档。不确定解决方案在这里。

  3. 我真的不喜欢没有子集合,我想我可以在没有子集合的情况下完成上述操作,只需将所有唯一属性合并到variants数组中。但后来我没有为每个变体提供独特的docId,而且我非常确定我需要它(还不完全确定)。它也没有解决我的可用属性问题。

    有关如何正确执行此操作的任何想法?有没有办法在没有子集合的情况下完成它?

1 个答案:

答案 0 :(得分:0)

原来这个问题的解决方案更多的是与algolia搜索而不是firestore。为了实现我想要的目标,我可以使我的firestore数据库与原来的数据库非常接近(不需要子集合),我只需要添加一个对象数组,其中包含每个变体的唯一信息(variants: [] )以及将各个文档绑定在一起作为彼此变体的标识符(distinct: 12345)。

这里的关键是aloglia的distinct功能,它允许对由特定键绑定在一起的项目进行重复删除。因此,在下面的示例中,我将Shirt项的三个变体与distinct: 12345字段绑定在一起。您必须进入aloglia仪表板才能启用distinct并设置密钥名称。现在只有其中一个变体会在搜索时显示(这取决于自定义排名或过滤器),但我可以通过变体字段访问所有变体的信息。这允许我为每个变体拥有唯一的id,并且每个变量的所有属性都可以在algolia搜索中过滤。它还允许我构建选择下拉列表以选择用户想要与之交互的变体。需要注意的是,添加了冗余,并且在更新项目变体时,需要使用云功能在所有变体中传播更改。但它有效并且问题解决了!

ParentCollection
    items
        ->docId_1
            ->name: 'Shirt,
            ->tags: ['tag1', 'tag2', 'tag3']
            ->attribute1: 'blah'
            ->attribute2: 'blahblah'
            ->distinct: 12345
            ->variants: [
                {
                 size: 'S',
                 available: true,
                 price: 5, 
                 docId: docId_1
                },
                {
                 size: 'M',
                 available: false,
                 price: 10,
                 docId: docId_2
                },
                {
                 size: 'L',
                 available: true,
                 price: 15, 
                 docId: docId_3
                }]
        ->docId_2
            ->name: 'Shirt'
            ->tags: ['tag1', 'tag2', 'tag3']
            ->attribute1: 'blah'
            ->attribute2: 'blahblah'
            ->distinct: 12345
            ->variants: [
                {
                 size: 'S',
                 available: true,
                 price: 5, 
                 docId: docId_1
                },
                {
                 size: 'M',
                 available: false,
                 price: 10,
                 docId: docId_2
                },
                {
                 size: 'L',
                 available: true,
                 price: 15, 
                 docId: docId_3
                }]
        ->docId_3
            ->name: 'Shirt'
            ->tags: ['tag1', 'tag2', 'tag3']
            ->attribute1: 'blah'
            ->attribute2: 'blahblah'
            ->distinct: 12345
            ->variants: [
                {
                 size: 'S',
                 available: true,
                 price: 5, 
                 docId: docId_1
                },
                {
                 size: 'M',
                 available: false,
                 price: 10,
                 docId: docId_2
                },
                {
                 size: 'L',
                 available: true,
                 price: 15, 
                 docId: docId_3
                }]