代码之家  ›  专栏  ›  技术社区  ›  rt_

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

  •  2
  • rt_  · 技术社区  · 6 年前

    因此,正如标题所示,我在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. 这将需要额外的db调用,因为Firestore在请求父集合时无法获取子集合。

    2. 一个大问题是,我需要为项目附加一个可用的属性,以前我在项目集合级别有它,但现在我有了变体,我需要将它放在每个变体上。如果我在父集合级别的变体数组中有它,我想我不能再过滤algolia搜索中的可用值,因为一个项目将有多个值。如果我在variants子集合中放置available,则algolia不会为其编制索引,因为它只是为Items集合中的文档编制索引。不确定这里的解决方案是什么。

    我真的不希望有子集合,我想我可以在没有子集合的情况下完成上述操作,只需将所有唯一属性合并到变体数组中。但是,我不会为每个变体都有一个唯一的docId,我很确定我需要它(目前还不完全确定)。此外,它也无法修复我的可用属性问题。

    如何正确地做到这一点,有什么想法吗?有没有办法不用子集合就可以做到这一点?

    1 回复  |  直到 6 年前
        1
  •  0
  •   rt_    6 年前

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

    这里的钥匙是aloglia的 distinct 允许对由特定键绑定在一起的项目进行重复数据消除的功能。因此,在下面的示例中,我将 Shirt 项目由 不同: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
                    }]