此模型的Firebase备选数据库设计



我真的被困在使用Firestore作为我的后台。因为每一个单一的数据库设计,我尝试结束与Firebase不允许几乎任何组合的子查询或嵌套过滤我需要。

领域很简单,我有一些课程有类别和语言,我想按类别和语言过滤这些课程。

我已经试过了:

集合:

[
courses,
categories,
languages,
]

文档样本:课程

{
id: 'pQYYsU80iLgZqTiYLkJXwHL25873',
title: 'Javascript II',
teacherName: 'Bob',
categories: ['javascript','nodejs'],
languages: ['english','spanish']
}

{
id: 'QJMzrwEJ6vRtPBsfSOVxojTMuHk1',
name: 'programming',
subcategories: ['programming','javascript','php','nodejs'],
keywords: ['computer', 'developing', 'web', 'developer', 'programming','javascript','php','nodejs']
}
语言>
{
id: 'AbMzrwC6vRRPBsfSOVx2jTMuHk1',
name: 'english',
code: 'en-US',
}

我想查询,即:所有关于'javascript''english'的课程。但由于array-contains不能嵌套多次,因此不可能在一次查询中获取它们。

我不能通过获取多个查询来实现,因为设备很快就会耗尽内存。

是否有任何域设计替代方案可以在单个查询中实现这一点?

但是不可能在一次查询中获取它们,因为数组包含不能嵌套多次。

是,您只能使用一次array-contains。如果允许更改文档结构,那么可以通过将数组数据类型更改为Map来解决这个问题,如下所示:

{
id: 'pQYYsU80iLgZqTiYLkJXwHL25873',
title: 'Javascript II',
teacherName: 'Bob',
categories: {
javascript = true,
nodejs = true
},
languages: {
english = true,
spanish = true
}
}

我想查询,即:所有关于'javascript'和'english'的课程。

使用上述模式,执行以下查询:

coursesRef
.where("categories.javascript", "==", true)
.where("languages.english", "==", true);

它会很好地工作。

Alex给出的优秀答案的另一个替代方案是添加一个新的字段,其中的值是可用的类别/语言组合:

category_language_pairs: ['javascript_english', 'javascript_spanish', 'nodejs_english', 'nodejs_spanish'],

有了这个字段,您的查询只需要一个条件:

coursesRef
.where("category_language_pairs", "array-contains", "javascript_english")

这当然会增大文档的大小,因此最好保留在类别/语言组合的数量不太高的情况下使用。