我在Firebase Firestore上有一个项目,我想在同一个子集合下的两个文档之间执行复合查询。我已经创建了Firestore所需的索引,并且如果字段在同一文档中,查询将完美执行。
举例说明我的情况:
采用以下结构:
- Users (root collection)
- User (document)
- userId
- username
- ...
--- Personalization (subcollection)
--- Alerts (document)
- myTags (array of strings)
- ...
--- Location (document)
- region (string)
- ...
我想执行一个查询,该查询首先验证用户region
(/Users/{userId}/Personalization/Location
)是否等于参考值。如果是这样,我希望它验证数组myTags
(/Users/{userId}/Personalization/Alerts
)是否包含某个标记。
这是我到目前为止可以获得的最接近的数字:
db.collectionGroup('Personalization').where('region', '==', 'California').where('myTags', 'array-contains', 'Macbook')
.get().then(querySnapshot => {
if (querySnapshot.empty) {
console.log('Result is empty');
} else {
console.log('Result found. ', querySnapshot.size, ' result(s).');
}
querySnapshot.forEach(doc => {
console.log(doc.id, ' => ', doc.data());
});
}).catch(error => {
console.error(error);
});
如果我的所有字段都在同一个文档下,则该查询非常有效,例如:
--- Personalization (subcollection)
--- Alerts (document)
- myTags (array of strings)
- region (string)
- ...
此外,我可以使两个查询完全独立地工作,如下所示:
db.collectionGroup('Personalization').where('myTags', 'array-contains', 'Macbook').get().then(querySnapshot => {
querySnapshot.forEach(element => {
console.log('Search only by tag => ', element.id, ' => ', element.data());
});
有没有一种方法可以使查询工作,同时仍在同一子集合下使用两个不同的文档,或者我必须使用同一文档进行复合查询?也许索引上有一些配置,或者类似的东西我也不知道,因为当您第一次尝试使用复合查询创建索引时,我只关注了Firebase为您提供的错误链接。
其他信息:
此外,如果有人知道Firestore上的一些复合查询示例,我将不胜感激。我已经阅读了文档,并看到了Firebase团队的一些视频,它们解释了Firestore的工作原理,但我感到缺少更复杂的示例来了解Firestore的工作原理。
答案 0 :(得分:2)
Firestore当前不支持逻辑OR类型查询,在逻辑OR类型查询中,您可以提供多个条件来进行匹配:
如您所见,它仅支持逻辑AND。当您提供两个where子句时,查询将仅提供同时满足这两个条件的文档。
如果要对多个条件实施逻辑或,则必须分别针对每个条件执行查询 ,并将结果合并到客户端代码中。这意味着您将要进行两个查询:
where('region', '==', 'California')
where('myTags', 'array-contains', 'Macbook')
然后等待两个查询结束并查看每个查询的结果。
答案 1 :(得分:1)
用.where('region', '==', 'California').where('myTags', 'array-contains', 'Macbook')
定义的compound query将不会返回两个不同的文档。
如文档(上面的链接)所述,此查询将仅返回与两个where子句匹配的文档 (“逻辑AND
”)。
如同一文档中所述:
Cloud Firestore不支持以下类型的查询:
- ...
- 逻辑或查询。在这种情况下,您应该为每个OR条件创建一个单独的查询,然后将查询结果合并到您的应用中。
- ...
如您在问题下方的评论中所述,一种解决方案是在regions
文档中添加一个额外的Alert
字段。