是否可以查询Firebase Firestore的1个文档,其中包含一组唯一的关键字而无需花费大量资金?

时间:2019-09-08 11:21:55

标签: firebase google-cloud-firestore

在博客文章的Firebase Firestore数据库中,我遇到了一项业务规则,该规则要求我强制执行,两个博客文章都不能共享匹配的关键字集。

顺序无关紧要,只是每个博客帖子必须包含一组唯一的关键字。

话虽如此。 是否可以构造一个查询来检查文档集合中是否存在与给定关键字对象匹配的关键字对象?没有嵌套数据,仅存储在我的Firestore文档中一个对象中的关键字列表

现在,很可能我确实需要另一个数据结构来实现此目的,但是目前我正在使用以下2个集合(更新:为清楚起见,此处缩短了,每个帖子可以包含1-30个关键字):

blogs (collection)
(blogA)
-- content
-- keywords: {car:true, truck:true, airplane:true}
(blogB)
-- content
-- keywords: {car:true, truck:true, train:true}

keywords (collection)
(car)
-- blogs: {blogA:true, blogB:true}
(truck)
-- blogs: {blogA:true, blogB:true}
(airplane)
-- blogs: {blogA:true}
(train)
-- blogs: {blogB:true}

以上面的数据为例,

一篇新的关键词为car, truck, airplane的博客文章将被拒绝

一篇新的关键词为car, truck, airplane, bus的博客文章将被接受

下面的

是用于云函数的可能逻辑作为示例解决方案,但是它有点荒谬,并且永远无法扩展。 因此,出于这个原因,我将省略很多涵盖所有情况的必要逻辑。我只是想把这个想法讲清楚。

每个新提交的关键字的查询关键字集合

-如果不存在-停止-允许新博客条目 -否则将创建2个空数组以供使用

  blogs[]
  matches[]

-对于提交的每个关键字,循环浏览其博客ID列表,并将其推入blogs[]数组中。

如果已经插入博客ID,则将博客ID推入matches[]数组中。

我们剩下一个数组matches[] ,其中包含所有博客文章的列表,其中包括两个或多个新提交的关键字

-if (matches[].length === 0)-停止-允许新博客条目

-否则,对于matches[]中的每个博客,从Firestore 中的博客文档中获取其关键字对象,但是如果有数百万个文档,则此循环将花费大量资金

-如果新关键字对象(按字母顺序排列)===博客关键字对象(按字母顺序排列)-停止-设置存在拒绝博客文章

如果matchs []数组中没有博客包含匹配的关键字集,那么我们知道我们有了一组新的唯一关键字-停止-允许博客文章

我必须相信有更好的方法。

1 个答案:

答案 0 :(得分:2)

当您具有唯一性要求时,请始终尝试使用必须唯一的值作为集合中文档的键。

由于键在定义上在集合中是唯一的,因此使用某些内容作为键隐式地保证键将是唯一的。这也意味着该检查将成为对特定文档是否存在的检查,而不是对所有文档进行值/值组合查询。

在您的情况下,您可以简单地按字母/字典顺序将类别连接起来以生成文档密钥。

采用这种方法,这些类别将产生关键:

Categories                   Document id/key
---------------------------+-----------------------
car, truck, airplane       | airplane_car_truck
truck, car, airplane       | airplane_car_truck
car, truck, airplane, bus  | airplane_bus_car_truck
truck, airplane, car, bus  | airplane_bus_car_truck

我使用_作为上面的分隔符,但是任何在您的类别中永远不会出现的分隔符都可以。