Firestore 如何实现检索不在已获取文档集合中的文档?
Firestore排除已拉取文档查询方案
这个需求是可以实现的,根据你已拉取文档的数量不同,有两种实现方式:
已拉取文档数量≤10:使用Firestore原生
not-in操作符
你可以直接从已存储的文档Set里提取所有文档ID,转为数组后传入查询条件即可,示例代码(Web端SDK为例):// 从Set中提取已拉取的文档ID数组 const fetchedIdList = Array.from(yourDocumentSet).map(doc => doc.id); // 构建查询,__name__是Firestore内置的文档ID字段 const searchQuery = db.collection('你的业务集合名') .where('你要匹配的搜索字段', '==', '用户输入的搜索字符串') .where('__name__', 'not-in', fetchedIdList);注意Firestore的
not-in操作符最多只支持传入10个对比值,超出限制会直接报错。已拉取文档数量>10:两种可选方案
- 优先使用分页游标方案,不需要自己维护已拉取文档Set,每次查询后记录最后一条返回文档的快照,下一次查询从该快照之后开始拉取,天然不会重复获取之前的内容:
// 首次查询 let lastDocSnapshot = null; const firstQuery = db.collection('你的业务集合名') .where('搜索字段', '==', '搜索字符串') .limit(20); const firstRes = await firstQuery.get(); // 记录最后一条文档快照 lastDocSnapshot = firstRes.docs[firstRes.docs.length - 1]; // 后续分页查询 const nextQuery = db.collection('你的业务集合名') .where('搜索字段', '==', '搜索字符串') .limit(20) .startAfter(lastDocSnapshot);- 如果你的业务逻辑必须自行维护已拉取Set,且超出10个的限制,你可以先查询所有符合搜索条件的文档,在前端代码中自行过滤掉Set中已存在的条目即可,该方案仅适合搜索结果总数据量不大的场景。
额外注意事项
- 上述用到的复合查询需要提前在Firestore控制台创建对应索引,首次执行查询如果报错,报错信息中会直接生成索引创建入口,点击创建后等待数分钟即可正常使用。
not-in查询会自动排除对应字段值为null的文档,如果你的搜索字段存在空值场景需要额外做兼容处理。
内容的提问来源于stack exchange,提问作者Fernando Contreras Aguilar
相关产品推荐
相关产品推荐

