这是我的Firebase数据库" / articles",里面有很多文章。用户可以(使用他/她自己的文章)列出对应于特定条件的其他文章。为了使文章能够通过查询测试,它必须属于用户的文章列在" tradableCategories"内的类别,同时该文章也需要有用户的权限。文章" tradableCategories"。
中的文章类别这是数据库结构:
"articles": {
"article1": {
"title": "Car",
"category": "vehicles",
"owner": "user1",
"tradableCategories": {
"furnishings": true,
"other": true,
"vehicles": true
},
"category_tradableCategories": {
"vehicles_furnishings": true,
"vehicles_other": true,
"vehicles_vehicles": true
}
},
"article2": {
"title": "Bike",
"category": "vehicles",
"owner": "user2",
"tradableCategories": {
"furnishings": true,
"other": true
"vehicles": true,
},
"category_tradableCategories": {
"vehicles_furnishings": true,
"vehicles_other": true,
"vehicles_vehicles": true
}
},
"article2": {
"title": "Couch",
"category": "furnishings",
"owner": "user2",
"tradableCategories": {
"furnishings": true,
"other": true,
"vehicles": true
},
"category_tradableCategories": {
"furnishings_furnishings": true,
"furnishings_other": true,
"furnishings_vehicles": true
}
},
...
}
user1拥有article1,想要查找家具,其他和车辆内的文章。那些符合条件的文章也必须查找article1的集合类别。可以使用SQL轻松完成查询:
SELECT *
FROM articles
WHERE category = ’vehicles’ /* This is article1’s category */
AND find_in_set(category, :tradableCategories) /* :tradableCategories is a stringified, comma-separated set of article1’s tradableCategories: “furnishings,other,vehicles” */
AND NOT owner = ‘user1’
正如您在数据库结构中看到的那样。我已经包含了另一个名为“category_tradableCategories”的对象。我在Stack Overflow上看到了各种答案,解释了如何使用两个条件组合成一个来搜索项目。这可能有效,但意味着我必须启动3个Firebase查询,因为我无法在tradableCategories中组合三个(或更多)不同的类别。
我担心这对Firebase来说太复杂了,但如果有任何有效的解决方案,我想要一些帮助。谢谢!
答案 0 :(得分:2)
在关系数据库中,您通常首先定义数据模型以匹配您要存储的数据,然后针对应用程序的用例编写查询。在NoSQL数据库中,您通常使用逆逻辑:您列出应用程序的用例列表,然后定义数据模型以匹配这些用例。
如果Firebase的API不直接支持您要构建的查询,则通常必须更改/扩充数据模型以允许该查询。这将导致存储更多数据和更复杂的更新,但优点是您可以更快,更简单地进行读取操作。
因此,在您的场景中:您需要一个不属于当前用户的三个类别之一的文章列表。该要求的最直接映射是按字面意思存储该列表:
user_articles
$uid
categories_1_2_3
articlekey1: true
articlekey2: true
这会使查询变得微不足道:ref.child("user_articles").child(currentUser.uid).child(categories).on("child_added"...
。
现在这可能会使非规范化和重复有点过头了。我们需要为每个用户/类别组合单独列出。因此,包含10个用户的3个类别的文章将最终出现在60个列表中。
您更有可能希望将这些文章按类别保存在所有用户的单个列表中。例如:
articles_by_category_with_owner
category_1
articlekey1: uid1
articlekey2: uid2
articlekey3: uid1
category_2
articlekey1: uid1
articlekey2: uid2
category_3
articlekey1: uid1
articlekey3: uid1
现在,您可以使用ref.child("articles_by_category_with_owner").child(category).on("child_added"...
获取category_1的所有文章键,然后执行“当前用户不拥有”过滤客户端。
在上面的列表中,我还删除了多个类别。这确实意味着您需要为每个类别读取一个节点。但实际上这并不像您预期的那么慢,因为Firebase会对这些请求进行管道处理(请参阅下面的链接)。
进一步推荐阅读/观看: