수집된 임의의 문서를 가져오는 Firestore 방법
P粉277305212
P粉277305212 2023-10-19 11:39:22
0
2
794

내 앱이 Firebase의 컬렉션에서 여러 문서를 무작위로 선택할 수 있는 것이 중요합니다.

(내가 아는 한) Firebase에는 이 작업을 수행하기 위한 쿼리를 구현하는 기본 제공 기본 함수가 없기 때문에 컬렉션이 있다고 가정하고 쿼리 커서를 사용하여 임의의 시작 및 끝 인덱스를 선택하는 것이 가장 먼저 생각났습니다. of 숫자 의 문서 수입니다.

이 접근 방식은 작동하지만 각 문서가 매번 이웃과 순차적으로 제공되므로 제한된 방식으로만 가능합니다. 그러나 상위 컬렉션 문서 쿼리에서 색인을 기준으로 문서를 선택할 수 있으면 무작위화를 달성할 수 있습니다. 문제는 이 작업을 수행하는 방법을 설명하는 문서를 찾을 수 없거나 이를 수행하는 것이 가능하더라도 찾을 수 없다는 것입니다.

이것이 제가 하고 싶은 일입니다. 다음 Firestore 아키텍처를 고려하세요.

으아아아

그런 다음 내 클라이언트 측(Swift 환경에 있음)에서 다음을 수행하는 쿼리를 작성하고 싶습니다.

으아아아

저도 비슷한 일을 할 수 있나요? 또는 비슷한 방식으로 임의의 문서를 선택하는 다른 방법이 있습니까?

도와주세요.

P粉277305212
P粉277305212

모든 응답(2)
P粉668113768

향후에 이 문제가 발생하는 모든 사람에게 도움이 되도록 이 글을 게시하세요.

자동 ID를 사용하는 경우 Dan McGrath의 답변에서와 같이 새 자동 ID를 생성하고 가장 가까운 자동 ID를 쿼리할 수 있습니다.

저는 최근 Firestore 컬렉션에서 무작위 인용문을 가져오는 데 필요한 무작위 인용문 API를 만들었습니다.
이것이 제가 이 문제를 해결한 방법입니다:

으아악

쿼리의 핵심은 다음과 같습니다.

으아악

문서가 발견되지 않으면 반대 작업으로 다시 호출하세요.

도움이 되기를 바랍니다!

P粉985686557

무작위로 생성된 색인과 간단한 쿼리를 사용하여 Cloud Firestore의 컬렉션 또는 컬렉션 그룹에서 문서를 무작위로 선택할 수 있습니다.

이 답변은 4개 부분으로 나누어져 있으며 각각 다른 옵션이 있습니다.

  1. 임의 인덱스 생성 방법
  2. 임의 인덱스를 쿼리하는 방법
  3. 여러 개의 무작위 문서를 선택하세요
  4. 일관적인 무작위성을 위해 다시 시드

임의 인덱스 생성 방법

이 답변의 기본은 오름차순 또는 내림차순으로 정렬할 때 모든 문서가 무작위로 정렬되는 인덱스 필드를 만드는 것입니다. 이를 생성하는 방법에는 여러 가지가 있으므로 가장 접근하기 쉬운 방법부터 시작하여 2를 살펴보겠습니다.

자동으로 버전 식별

클라이언트 라이브러리에서 제공하는 무작위로 생성된 자동 ID를 사용하는 경우 동일한 시스템을 사용하여 문서를 무작위로 선택할 수 있습니다. 이 경우 무작위로 정렬된 인덱스 문서 ID입니다.

나중에 쿼리 섹션에서 생성한 임의의 값은 새로운 자동 ID(iOS, Android, Web)이고 쿼리하는 필드는 __name__ 필드이며 '나중에 언급된' 낮은 값은 " 빈 문자열. 이는 무작위 인덱스를 생성하는 가장 간단한 방법이며 언어 및 플랫폼에 관계없이 작동합니다.

기본적으로 문서 이름(__name__) 仅按升序索引,并且除了删除和重新创建之外,您也无法重命名现有文档。如果您需要其中任何一个,您仍然可以使用此方法,只需将自动 ID 存储为名为 random)은 오름차순으로만 색인이 생성되며, 기존 문서를 삭제하고 다시 만드는 방법 외에는 이름을 바꿀 수도 없습니다. 둘 중 하나가 필요한 경우에도 이 방법을 사용할 수 있습니다. 이 목적으로 문서 이름을 오버로드하는 대신 자동 ID를

라는 실제 필드로 저장하면 됩니다.

임의의 정수 버전

random문서를 작성할 때 먼저 제한된 범위에서 임의의 정수를 생성하고

라는 필드에 설정합니다. 예상되는 문서 수에 따라 다양한 경계 범위를 사용하여 공간을 절약하거나 충돌 위험을 줄일 수 있습니다(이로 인해 이 기술의 효율성이 감소함).

고려 사항이 다르므로 어떤 언어가 필요한지 고려해야 합니다. Swift는 간단하지만 JavaScript에는 주목할만한 문제가 있습니다. 🎜
  • 32비트 정수: 소규모(~10K 충돌 가능성이 적음) 데이터세트에 이상적입니다
  • 64비트 정수: 대규모 데이터 세트(참고: JavaScript 자체에서는 지원되지 않음, 아직)

문서가 무작위로 정렬된 색인이 생성됩니다. 나중에 쿼리 섹션에서 생성하는 임의의 값은 이러한 값 중 하나가 되며 나중에 언급되는 "낮은 값"은 -1이 됩니다.

임의 인덱스를 쿼리하는 방법

이제 임의 인덱스가 있으므로 이를 쿼리해야 합니다. 아래에서는 임의의 문서 1개를 선택하는 몇 가지 간단한 변형과 ​​여러 개의 1개 문서를 선택하는 옵션을 살펴봅니다.

이러한 모든 옵션에 대해 문서 작성 시 생성한 인덱스 값과 동일한 형식의 새로운 임의 값을 생성해야 하며, 아래 변수 random로 표시됩니다. 이 값을 사용하여 인덱스에서 임의의 지점을 찾습니다.

둘러싸기

이제 임의의 값이 있으므로 개별 문서를 쿼리할 수 있습니다.

으아아아

서류가 반송되었는지 확인해주세요. 그렇지 않은 경우 무작위 인덱스의 "낮은 값"을 사용하여 다시 쿼리합니다. 예를 들어 임의의 정수를 계산하는 경우 lowValue0:

으아아아

문서가 1개 있는 한, 최소 1개의 문서를 반환하는 것이 보장됩니다.

양방향

랩 방법은 구현이 간단하며 오름차순 인덱싱만 활성화하여 스토리지를 최적화할 수 있습니다. 한 가지 단점은 가치가 부당하게 보호될 수 있다는 점이다. 예를 들어, 10K의 처음 3개 문서(A, B, C)에 임의의 인덱스 값 A:409496, B:436496, C:818992가 있는 경우 A와 C가 선택될 확률은 1/10K 미만입니다. , B는 A가 근거리로부터 효과적으로 보호되고 확률이 약 1/160K에 불과하기 때문에 선택됩니다.

임의로 선택할 수 있습니다. >=단방향 쿼리와 값을 찾을 수 없을 때 래핑하는 대신 인덱스 저장 공간을 두 배로 늘리는 비용으로 값을 부당하게 마스킹할 가능성을 절반으로 줄입니다.

한 방향으로 결과가 반환되지 않으면 다른 방향으로 전환하세요.

으아아아

여러 개의 무작위 문서를 선택하세요

일반적으로 한 번에 여러 개의 무작위 문서를 선택해야 합니다. 원하는 절충점에 따라 위의 기술을 적용하는 두 가지 방법이 있습니다.

헹구고 반복

이 방법은 매우 간단합니다. 매번 새로운 임의의 정수를 선택하는 것을 포함하여 프로세스를 반복하십시오.

이 방법을 사용하면 동일한 패턴이 반복적으로 표시되는 것에 대해 걱정할 필요 없이 임의의 문서 순서를 얻을 수 있습니다.

단점은 각 문서를 제공하기 위해 별도의 왕복이 필요하므로 다음 방법보다 속도가 느리다는 것입니다.

계속 힘내세요

이 방법에서는 필요한 서류의 개수를 늘리면 됩니다. 통화 중에 0..limit 문서를 반환할 수 있기 때문에 이는 약간 복잡합니다. 그런 다음 동일한 방법으로 누락된 문서를 가져와야 하지만 제한 사항은 차이점만 줄어듭니다. 총 문서 수가 요청한 것보다 많다는 것을 알고 있는 경우 두 번째 호출에서는 충분한 문서가 검색되지 않지만 첫 번째 호출에서는 검색되지 않는 극단적인 경우를 무시하여 최적화할 수 있습니다.

이 솔루션의 단점은 반복 시퀀스입니다. 문서가 무작위로 정렬되어 있지만 범위가 겹치는 경우 이전에 본 것과 동일한 패턴이 표시됩니다. 이러한 우려를 완화할 수 있는 방법이 있으며, 이에 대해서는 재시드에 대한 다음 섹션에서 논의하겠습니다.

이 방법은 최선의 경우 한 번의 통화로 모든 문서를 요청하고 최악의 경우 두 번의 통화로 모든 문서를 요청하기 때문에 "헹굼 및 반복"보다 빠릅니다.

일관적인 무작위성을 위해 다시 시드

문서 세트가 정적인 경우 이 방법은 무작위로 문서를 제공하지만 각 문서를 반환할 확률도 정적인 것입니다. 이는 일부 값이 초기에 얻은 무작위 값에 따라 확률이 불공평하게 낮거나 높을 수 있기 때문에 문제가 됩니다. 많은 사용 사례에서는 이것이 괜찮지만 일부에서는 1개의 문서가 반환될 가능성이 더 균등하도록 장기 무작위성을 높이고 싶을 수도 있습니다.

삽입된 문서는 중간에 얽혀 확률이 점차 변하며, 삭제된 문서도 마찬가지이니 참고하세요. 주어진 문서 수에 비해 삽입/삭제 비율이 너무 작은 경우 이 문제를 해결하기 위한 몇 가지 전략이 있습니다.

다중 무작위

재시드에 대해 걱정할 필요가 없습니다. 언제든지 문서당 여러 개의 무작위 인덱스를 생성하고 매번 그 중 하나를 무작위로 선택할 수 있습니다. 예를 들어 필드 random를 하위 필드 1~3을 포함하는 맵으로 설정합니다.

으아아아

이제 무작위로 무작위로 쿼리하여 더 큰 무작위성 분포를 생성합니다. 이는 본질적으로 증가된 저장 공간을 사용하여 다시 시드하는 데 필요한 계산(문서 작성)을 절약합니다.

작성하는 동안 다시 시드

문서가 업데이트될 때마다 random 필드의 임의 값이 다시 생성됩니다. 이렇게 하면 문서가 임의의 인덱스로 이동됩니다.

읽으면 다시 시드

생성된 랜덤 값이 고르게 분포되지 않으면(랜덤이므로 이는 예상되는 현상임) 부적절한 시점에 동일한 문서가 선택될 수 있습니다. 이 문제는 무작위로 선택된 문서를 읽은 후 새로운 무작위 값으로 업데이트하면 쉽게 해결할 수 있습니다.

쓰기는 비용이 더 많이 들고 핫스팟이 될 수 있으므로 읽기 시간의 하위 집합에서만 업데이트하도록 선택할 수 있습니다(예: if random(0,100) === 0) update;).

최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿