在Firebase Cloud Firestore中,我在集合中有“user_goals”,目标可能是预定义的目标(master_id:“XXXX”)或自定义目标(无“master_id”键)
在JavaScript中,我需要编写两个函数,一个用于获取所有预定义目标,另一个用于获取所有自定义目标。
我有一些变通方法来获得自定义目标,通过将“master_id”设置为“”空字符串,并能够获得如下:
db.collection('user_goals')
.where('challenge_id', '==', '') // workaround works
.get()
但这仍然不是正确的方法,我继续使用这个预定义的目标,其中它有一个“master_id”如下
db.collection('user_goals')
.where('challenge_id', '<', '') // this workaround
.where('challenge_id', '>', '') // is not working
.get()
由于Firestore没有“!=”操作符,我需要使用“〈”和“〉”操作符,但仍然没有成功。
问题:忽略这些解决方法,通过检查特定字段是否存在来获取文档的首选方法是什么?
7条答案
按热度按时间kmb7vmvb1#
作为@Emile Moureau解决方案。我更喜欢
使用该字段查询文档存在。因为它可以处理任何类型的数据和任何值,即使是
null
。正如@Doug史蒂文森所说:
您不能查询Firestore中不存在的内容。字段需要存在,以便Firestore索引知道它。
没有该字段,您无法查询文档。至少目前是这样。
rdlzhqv92#
获取存在指定字段的文档的首选方法是使用:
如Firebase文档中所述:
因此,@hisoft提供的答案是有效的。我只是决定提供官方来源,因为问题是首选的方式。
yrwegjxp3#
Firestore是一个indexed database。对于文档中的每个字段,该文档将根据您的配置适当地插入到该字段的索引中。如果文档不包含特定的字段(像
challenge_id
)它将不出现在该字段的索引中,并且将从该字段的查询中省略。通常,由于Firestore的设计方式,查询应该在一个连续的扫描中读取索引。在引入!=
和not-in
运算符之前,这意味着你不能排除特定的值,因为这需要跳过索引的部分。当试图在单个查询中使用独占范围(v<2 || v>4
)时,仍然会遇到这种限制。字段值将根据实时数据库排序顺序进行排序,但在遇到重复项时,可以按多个字段而不是仅按文档ID对结果进行排序。
Firestore值排序顺序
null
false
true
不等式
!=
/<>
!=
和not-in
运算符之前不等式是如何工作的。请参阅有关如何使用这些运算符的文档。以下部分将保留用于历史目的。*要在Firestore上执行不等式查询,您必须修改查询,以便可以通过从Firestore的索引阅读来读取。对于不等式,这是通过使用两个查询来完成的-一个查询小于
equality
的值,另一个查询大于相等的值。举个简单的例子,假设我想要不等于3的数字。
可以写成
将此应用于Firestore,您可以转换此(以前)不正确的查询:
这两个查询并合并它们的结果:
重要提示:请求用户必须能够读取所有与查询匹配的文档,才不会出现权限错误。
缺少/未定义字段
简单地说,在Firestore中,如果一个字段没有出现在文档中,该文档就不会出现在该字段的索引中。这与实时数据库不同,在实时数据库中,省略的字段的值为
null
。由于NoSQL数据库的性质,您正在使用的模式可能会更改,从而使旧文档缺少字段,因此您可能需要一个解决方案来“修补数据库”。为此,您将遍历集合并将新字段添加到缺少字段的文档中。
为了避免权限错误,最好使用具有服务帐户的Admin SDK进行这些调整,但您可以使用具有数据库适当读/写访问权限的用户使用常规SDK进行此调整。
这个函数循环遍历整个查询,并且只执行一次。
然后,您可以使用以下命令应用更改:
上面的函数也可以调整,以允许基于文档的其他字段计算默认值:
u3r8eeie4#
我使用的解决方案是:
用途:
.where('field', '>', ''),
这里的“场”就是我们要找的场!
lnvxswe25#
正如你所说的,不可能基于
!=
进行过滤。如果可能的话,我会添加一个额外的字段来定义目标类型。可以在安全规则中使用!=
,沿着各种字符串比较方法,这样你就可以根据你的challenge_id
强制执行正确的目标类型。指定目标类型
创建一个
type
字段并基于此字段进行筛选。type: master
或type: custom
并搜索.where('type', '==', 'master')
或搜索自定义。标记自定义目标
创建
customGoal
字段,可以是true
或false
。customGoal: true
并搜索.where('customGoal', '==', true)
或false(根据需要)。更新
现在可以在Cloud Firestore中执行!=查询了
bfhwhh0e6#
Firestore确实能接受布尔值,这是一个东西!而且可以是
orderBy
‘d。所以经常,像现在这样,为了这个,我把这个加入到数组中-从
onSnapshot
或get
推送,使用.get().then(
进行开发...这样,我可以使用
orderBy
而不是where
进行查询sbtkgmzw7#
这不是一个理想的解决方案,但当字段不存在时,我的解决方案如下:
请注意,它会影响你的阅读计数很多,所以只有使用这个,如果你有小的收集或可以负担得起的读取。