Reactjs 如何筛选大型Firestore列表的数据?

Reactjs 如何筛选大型Firestore列表的数据?,reactjs,google-cloud-firestore,Reactjs,Google Cloud Firestore,在下面的代码中,我从Firestore数据库获取用户并将其传递给视图。该视图有一个输入字段,用于在键入时搜索用户并过滤结果: import React, { useState, useEffect } from "react"; import axios from "axios"; export default function App() { const [users, setUsers] = useState([]); const [sear

在下面的代码中,我从Firestore数据库获取用户并将其传递给视图。该视图有一个输入字段,用于在键入时搜索用户并过滤结果:

import React, { useState, useEffect } from "react";
import axios from "axios";

export default function App() {
  const [users, setUsers] = useState([]);
  const [search, setSearch] = useState("");

  useEffect(() => {
    firebase
    .firestore()
    .collection('users')
    .onSnapshot((fetchedUsers) => {
       setUsers(fetchedUsers.docs.map((user) => user.data()));
    }).catch((error) => {
       // error handling
    });
  }, [setUsers]);

  return (
    <div className="App">
      <input
        type="text"
        placeholder="Search User..."
        value={search}
        onChange={(e) => setSearch(e.target.value)}
        style={{ marginBottom: "30px" }}
      />
      {users
        .filter((e) => e.name.toLowerCase().includes(search.toLowerCase()))
        .map((user) => (
          <div>{user.name}</div>
        ))}
    </div>
  );
}
import React,{useState,useffect}来自“React”;
从“axios”导入axios;
导出默认函数App(){
const[users,setUsers]=useState([]);
const[search,setSearch]=useState(“”);
useffect(()=>{
火基
.firestore()
.collection('用户')
.onSnapshot((fetchedUsers)=>{
setUsers(fetchedUsers.docs.map((user)=>user.data());
}).catch((错误)=>{
//错误处理
});
},[setUsers]);
返回(
setSearch(e.target.value)}
样式={{marginBottom:“30px”}
/>
{用户
.filter((e)=>e.name.toLowerCase().includes(search.toLowerCase()))
.map((用户)=>(
{user.name}
))}
);
}
我正在从Firestore获取用户,每天添加的用户超过1000人。因此,每次访问用户列表的次数与Firestore读取的次数相同


我怎样才能减少阅读量而不失去在打字时搜索用户的可能性?我面临这个问题,因为当我添加分页或仅获取最近50个用户时,我没有可供筛选的完整列表。

在查看firestore文档时,我发现它具有查询支持

如果我的理解正确,您需要过滤掉结果,这可以委托给firestore


为了减少您对firestore的呼叫次数,您可以通过阅读您的问题来实现
debounce

,您似乎希望在用户键入输入元素时限制对firestore的呼叫。为此,我将使用
useffect
中的
setTimeout
函数延迟调用firestore,直到用户停止键入后
500毫秒。下面是对
useffect
功能的更改

在实现超时功能后,需要使用
where
功能过滤数据。此函数接受三个参数
([search for]、[operator]、[what to match])
,因此,在您的情况下,您将拥有
('name','==',search)
。请在下面查找代码


我不确定是否需要重新表述我的问题。例如,我有2000个用户,目前我获取所有,这意味着2000次读取。例如,我可以添加分页以仅获取10。这是我基本上想要的,但是当我这样做的时候,我不能使用过滤器,因为我只有10个用户要过滤,我想过滤所有的。@t.Karter所以基本上,你的过滤器会遍历所有2000个用户,找到符合某个标准的用户,你不希望它这样做是正确的吗?这就是问题所在——不知何故,我会说我需要所有用户都能够过滤它们。但我并不总是过滤。可以用分页显示最后10个用户。因此,基本上第一次提取有一个
.limit(10)
。但当我现在想要过滤的时候,我需要我所想的一切。或者在Firestore中有一个过滤技巧,只读取过滤结果。我不知道Firestore API,但如果你在React应用程序中获取每个请求的所有2000个用户并对其进行过滤,你需要找到Firestore API的过滤方法。原因是,随着应用程序中用户数量的增加,您可能会迫使客户端在每次搜索中对数千个用户进行排序,这对性能极为不利。@T.Karter我编辑了我的答案,希望能有所帮助。我认为这解决了我的问题。在我真正的应用程序中,我已经在使用Firestore了。但我希望避免一次获取所有用户,因为有很多用户。但是,当我想对它们进行反应性筛选时,我需要一些东西——它们只有在我进行筛选时才需要。@T.Karter“Bcz我不能对上述帖子发表评论,这里是对你有用的东西”基本上你自己回答了这个问题。您需要结合使用过滤和限制(想想分页),但这需要直接在firestore上实现。Bcz如果要减少读取,则无法在客户端1上获取所有数据并进行筛选。查询Firestore 2。限制结果3。用去Bouncing对上面的配对进行分页,您可以进一步减少呼叫数量。您的意思是将超时应答与去Bouncing配对?你能举个例子吗?
useEffect(() => {

 // Adding the search variable to the array of the second useEffect argument
 // will cause this useEffect to run on every change to the search variable, which
 // is what we want since we do not know when the user will stop typing.

 // Also to filter user's, use the 'where' function, which has three parameters.

 const timeout = setTimeout(() => {
  firebase
    .firestore()
    .collection('users')
    .where('name', 'in', search)
    .onSnapshot((fetchedUsers) => {
       setUsers(fetchedUsers.docs.map((user) => user.data()));
    .catch(err => {
      // catch error
    });
 }, 500);

 // Clean up timeout
 return () => clearTimeout(timeout)

}, [search, setUsers]);