You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Firestore中查询数组长度,筛选仅含1个ID的数组对应的文档

解决方案

方案1:新增冗余统计字段(官方推荐,性能最优)

Firestore本身没有原生支持按数组长度查询的语法,官方最推荐的实现方式是新增一个和数组长度同步的数字字段:

  • 你可以给thread文档新增一个readUserIDsLength字段,每次对readUserIDs做增删改操作时,同步更新这个字段的数值为当前数组的长度
  • 之后直接按这个字段筛选即可,查询性能和普通字段查询完全一致,没有额外开销

对应的查询代码修改如下:

const notification = () => {
  channelsRef
    .where('channelID', '==', item.id)
    .get()
    .then((querySnapshot) => {
      querySnapshot.forEach((doc) => {
        doc.ref
          .collection('thread')
          .where('senderID', '==', item.participants[0].id)
          // 直接筛选数组长度为1的文档
          .where('readUserIDsLength', '==', 1)
          .get()
          .then((querySnapshot) => {
            console.log('size', querySnapshot.size);
            querySnapshot.forEach((thread) => {
              console.log('thread数据', thread.data());
            });
          });
      });
    });
};

方案2:利用数组下标存在性查询(无字段改动,适合小长度数组场景)

如果你的业务场景中readUserIDs数组最大长度不会超过10,也不想新增字段,可以通过判断指定下标是否存在的方式来筛选:

  • 要筛选数组长度恰好为1的文档,只需要满足两个条件:下标0存在、下标1不存在
  • 注意:这个方法仅适用于数组元素不会为null的场景,同时需要提前在Firestore控制台创建对应的复合索引

对应的查询代码修改如下:

const notification = () => {
  channelsRef
    .where('channelID', '==', item.id)
    .get()
    .then((querySnapshot) => {
      querySnapshot.forEach((doc) => {
        doc.ref
          .collection('thread')
          .where('senderID', '==', item.participants[0].id)
          // 下标0存在说明数组长度至少为1
          .where('readUserIDs.0', '!=', null)
          // 下标1不存在说明数组长度小于2,两个条件结合就是长度恰好为1
          .where('readUserIDs.1', '==', null)
          .get()
          .then((querySnapshot) => {
            console.log('size', querySnapshot.size);
            querySnapshot.forEach((thread) => {
              console.log('thread数据', thread.data());
            });
          });
      });
    });
};

内容的提问来源于stack exchange,提问作者Xwingoga06

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 12:45:04