Firestore:按文档数组中的项目查询

43

我有两个集合"照片""用户",每个"用户"文档都有一个或多个带有数组的照片ID

photos > 5528c46b > name: "Photo1"
         a1e820eb > name: "Photo2"
         32d410a7 > name: "Photo3"
users > acd02b1d > name: "John", photos: ["5528c46b"]
        67f60ad3 > name: "Tom", photos: ["5528c46b", "32d410a7"]
        7332ec75 > name: "Sara", photos: ["a1e820eb"]
        9f4edcc1 > name: "Anna", photos: ["32d410a7"]

我想获取所有具有一个或多个特定照片ID的用户。

有没有什么方法可以实现这个目标?

5个回答

34

参见Henry 的答案,因为我们还没有提供数组包含查询功能。

不幸的是目前还没有,但它已经在我们的路线图上。

同时,您需要使用一个类似于下面这样的 map:

photos: {
    id1: true
    id2: true
}

现在,您可以通过筛选 photos.id1 == true 来查找所有 ID 为 1 的用户。

请阅读Firebase 文档以了解有关查询此类集合的更多信息。


8
这个路线图有发布在某个地方吗?只是好奇。 - Jaap Weijland
2
@DanMcGrath 这个功能/路线图有任何更新吗? - Gal Bracha
8
Firestore不允许我这样查询数据,除非针对每个可能的ID建立索引。是否有一种方法可以不需要索引,或者使用动态索引? - Kevin Beal
2
正如@KevinBeal所提到的,最大的问题是如果需要复合查询,则无法索引键。这对于任何高级查询功能来说都是一个相当大的障碍。 - aglassman
3
可以,但只能针对单个参数。您可以使用.where('photos', 'array-contains','id1'),但是您无法使用.where('photos', 'array-contains',['id1','id2']) - wube
显示剩余9条评论

30

1
好的,那花了一些时间:D 我正在处理一个项目,需要这个功能,很高兴我落后了足够长的时间,让Firebase团队领先:p - madprogramer
3
很遗憾,目前无法用少量的“array-contains”值进行查询。 - Bohdan Didukh
@BohdanDidukh 你尝试过链式调用吗? .where(..).where(...)? - Henry
4
@Henry,是的,我试过了。Firebase服务器返回错误消息: FirebaseError:无效的查询。查询仅支持单个array-contains过滤器。 - Bohdan Didukh
是否可以使用对象键的值查询对象数组,例如{arrayItems:[{id:123,....},{id:234,...}] ...},并执行类似.where('arrayItems','array-contains','id = 123')的操作?该语法似乎不起作用,但我仍然希望有一种方法可以做到这样。请给予建议。 - vir us

5

以下是对答案的一些扩展,因为有些人似乎对每个键都必须制作索引感到困惑,Firestore已经为您的数据创建了索引,因此您可以进行简单查询,例如:

documentReference.where('param','==','value').onSnapshot(...)

但是,除非您为这些参数索引数据,否则无法执行复合查询。因此,您需要索引才能执行诸如以下操作:

 documentReference.where('param','==','value').where(..otherparams...).onSnapshot(...)

只要您需要拍摄证件照,就可以将它们保存为HTML格式。
usersCollection :                        (a collection)
    uidA:                                (a document)
         photoField:                     (a field value that is a map or object)
            fieldID1 : true              (a property of the photoField)
            fieldID2 : true              (a property of the photoField)
            etc ...  

您可以直接查询在其photoField中包含fieldID1的用户,无需形成任何索引或像下面这样的模疑问搜索。

firestore.doc('usersCollection/uidA').where('photoField.fieldID1','==',true).onSnapshot(...)

1

自2019年11月起,Firestore现已添加了“in”查询功能。

根据公告文章所述:

使用'in'查询,您可以在单个查询中查询特定字段的多个值(最多10个)。通过传递包含您要搜索的所有值的列表,Cloud Firestore将匹配任何字段等于这些值之一的文档。


1

使用Firebase 9版(2021年12月更新):

您可以在"while()"中使用"array-contains"一个单一的照片文档ID,以获取所有拥有该照片的用户

import {
  query,
  collection,
  where,
  getDocs
} from "firebase/firestore";

// Here
const q = query(
  collection(db, "users"),
  where("photos", "array-contains", "5528c46b")
);
// Here

const usersDocsSnap = await getDocs(q);

usersDocsSnap .forEach((doc) => {
  console.log(doc.data()); // "John's doc", "Tom's doc"
});

您可以在“while()”中使用“array-contains-any”和一个或多个带有数组的照片文档ID,以获取更多相应的用户。
import {
  query,
  collection,
  where,
  getDocs
} from "firebase/firestore";

// Here
const q = query(
  collection(db, "users"),
  where("photos", "array-contains-any", ["5528c46b", "a1e820eb"])
);
// Here

const usersDocsSnap = await getDocs(q);

usersDocsSnap .forEach((doc) => {
  console.log(doc.data()); // "John's doc", "Tom's doc", "Sara's doc"
});

如果["5528c46b", "a1e820eb"]在你的React状态中怎么办? - a7dc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接