본문 바로가기

🌼 TIL

데이터 모델링 개편으로 비효율적인 데이터 요청 줄이기

비효율적인 초기 데이터 모델링으로 인해 발생한 filter,map 남발 현상 발견

 //* post CollectionCategory 기준 데이터 가져오기
  const getTownDatas = async ({ queryKey }: { queryKey: string[] }) => {
    const [_, town] = queryKey;
    const response: { id: string }[] = [];
    let q = query(
      collection(dbService, 'post'),
      where('town', '==', town),
      orderBy('createdAt', 'desc')
    );

    const querySnapshot = await getDocs(q);
	@@ -29,19 +27,12 @@ const CollectionCategory = ({ value, postData, collectionData }: any) => {
    return response;
  };

  //* useQuery 사용해서 내가 컬렉션한 포스터의 town의 모든 postData들
  const { data } = useQuery(['data', value], getTownDatas);

  //* 모든 collection중 내가 collector에 내이름이 있는(내가 선택한) 포스터들
  const collectorList = collectionData?.filter((item: { collector: any[] }) => {
    return item.collector?.find((item) =>
      authService.currentUser?.uid.includes(item)
    );
  });

  //* 내가 담은 collection의 uid값
  const myCollectionUid = collectorList?.map((item: { uid: any }) => item.uid);
  //* 모든 포스터들 중 내가 담은 collection의 uid와 비교허여 일치하는 값
  const MyCollectionTownItem = data?.filter((item: { id: string }) =>
    myCollectionUid?.includes(item.id)
  );
  
const { data } = useQuery('data', getData);
  //* 전체에서 가져온 데이터에서 내가 작성한 포스터들만 가져왔다.
  const myPostList = data?.map((item: any) => {
    if (item.creator === authService.currentUser?.uid) {
      return item.id;
    }
  });

  // * 포스터 data중 내가 만든 것
  const categoryId = data?.filter((item: { id: string }) =>
    myPostList?.includes(item.id)
  );
  //* 만든 것 중 town 값만 고르기
  const myCollectPost = categoryId?.filter((item: { town: string }) => {
    return item.town;
  });
    //* post town 기준 데이터 가져오기
  const getTownData = async ({ queryKey }: { queryKey: string[] }) => {
    const [_, town] = queryKey;
    const response: { id: string }[] = [];
    let q = query(
      collection(dbService, 'post'),
      where('town', '==', town),
      orderBy('createdAt', 'desc')
    );

    const querySnapshot = await getDocs(q);
    querySnapshot.forEach((doc) => {
      response.push({ id: doc.id, ...doc.data() });
    });

    return response;
  };

  //* useQuery 사용해서 town 데이터 불러오기
  //* => 해당 town의 data들
  const { data } = useQuery(['data', value], getTownData);

  //* town데이터 creator 와 내 id가 같으면 그 item을 출력
  const myPostList = data?.filter(
    (item: any) => item.creator === authService.currentUser?.uid
  );

문제점

원하는 데이터를 찾기위해 filter와 map을 10회 이상 남발하게 되었다.

이 과정에서 데이터 요청값이 필요 이상으로 많이 발생하였고, 초기 데이터모델링에  문제가 있다고 판단하였다.

해결방법

- useQuery의 select 옵션 사용으로 쿼리단계에서 필요한 데이터만 불러올 수 있지만, 초기 데이터 모델링으로 활용할 수 있는 기능들이 효율이 떨어진다 판단하였고 데이터 모델링을 새로 구축하는게 이후의 추가기능 구현에 더욱 효율적이라고 판단했다.

- 데이터 모델링을 개편하여 firestore에 새로운 collection을 만들어 필요한 데이터만 구축하게 되었다. 

 

 

 //* useQuery 사용해서 데이터 불러오기
  const { data } = useQuery(['data', userUid], getMyPost);
  console.log('data', data);

  //* 만든 것 중 town 값만 고르기
  const myCollectPost = data?.filter((item: { town: string }) => {
    return item.town;
  });
  //* town값을 골라 map 돌리기
  
const Town = ({ value, myPostData }: { value: string; myPostData: any }) => {
  const [more, setMore] = useState(true);

  // * 내 게시물 town 추출
  const myPostTownList = myPostData?.filter((item: any) => item.town === value);

불필요한 filter,map반복문을 제거하고 효율적으로 데이터를 불러올 수 있었다.