Firebase Firestore查询超过10个元素的数组

5t7ly7z5  于 2022-11-17  发布在  其他
关注(0)|答案(5)|浏览(221)

[

x

]的第一个字符串
我尝试使用用户设置查询后收集,但设置是一个超过10个元素的数组,没有返回任何内容。我知道文档确实提到了10个元素的限制,有人知道解决方法吗?

firebaseApp.collection('posts')
            .where("newTag", "in", mySettings)
            .get()
let array = [];
        posts.forEach((post) => {
            array.push(post.data());
        });

dispatch({ type: ActionTypes.GET_POSTS, payload: array });
2nbm6dog

2nbm6dog1#

一个简单的数组分块函数可以解决您的问题:

const chunkArray = (list: any[], chunk: number): any[][] => {
    const result = [];

    for (let i = 0; i < list.length; i += chunk) {
        result.push(list.slice(i, i + chunk));
    }

    return result;
};

export { chunkArray };

然后,一个用于等待黑客来获取快照的方法也可以工作:

const snaps_collection: FirebaseFirestore.QuerySnapshot[] = [];

  for await (const snap of chunks.map(
    async (chunk) =>
      await database
        .collection("collection_name")
        .where("id", "in", chunk)
        .get()
  )) {
    snaps_collection.push(snap);
  }
35g0bw71

35g0bw712#

解决方法是分别对mySettings中的每个项执行查询,然后在客户端合并结果。或者,将mySettings拆分为另一个数组集合,每个数组包含10个或更少的项,分别对其中的每个项执行查询,然后在客户端合并结果。

flseospp

flseospp3#

执行mysettings的其中using a chunk of the array,每个块的最大大小为10,然后将结果加入单个数组

zkure5ic

zkure5ic4#

这个解决方案使用typescript,你可以把这个转换成你的编程语言。
时间复杂性:而循环运行length / 10次。

export async function getUsersByIds(ids: [string]) {
    let users = []
    const limit = 10

    while (ids.length) {
        const res = await db
            .collection('users')
            .where('uid', 'in', ids.slice(0, limit))
            .get()
        const _users = res.docs.map((doc) => {
            const _data = doc.data() as UserModel
            _data.docId = doc.id
            return _data
        })

        users.push(..._users)
        ids.splice(0, limit)
    }

    return users
}
ugmeyewa

ugmeyewa5#

下面是更多的Typescript eslint友好方式(不使用any
ArrayUtils.ts中的数组块方法

export function chunk<M>(array: Array<M>, chunkSize: number) {
  const ans: Array<Array<M>> = [];
  for (let i = 0; i < array.length; i += chunkSize) {
    ans[Math.floor(i / chunkSize)] = array.slice(i, i + chunkSize);
  }
  return ans;
}

现在在FirebaseUtils.kt中,您可以写入

import { chunk } from "./ArrayUtils";

export async function inQuery<M>(
  docRef: FirebaseFirestore.CollectionReference,
  field: string | FirebaseFirestore.FieldPath,
  values: Array<string>
) {
  const querySnapshots = await Promise.all(
    chunk(values, 10).map((chunkedArray) => {
      return docRef.where(field, "in", chunkedArray).get();
    })
  );
  return querySnapshots
    .flatMap((querySnapshot) => querySnapshot.docs)
    .map((documentData) => documentData.data() as M);
}

this相比几乎没有优势答案
1.重构为适当的实用程序方法以实现可重用性
1.使用Promise.all,它是并行的,比for await更推荐使用,因为当我们没有预先做出所有承诺时,会使用后者。请参见this

相关问题