유사한 배열이있는 Firestore 쿼리 문서 (Node.js / Admin SDK)

Aug 16 2020

이 배열이 있다고 상상해보십시오.

[10.3, 14, 12.4, 3.5]

DB에는 해당 배열이있는 두 개의 문서도 있습니다.

First document -> [10, 13.1, 0, -10]
Second document -> [0, 0, 0, 0]

이제 동일한 두 배열 (각 배열간에 교대로)을 가진 +1000000 개의 문서가 있다고 가정합니다. 현재 배열과 비슷한 값을 가진 모든 문서를 가져올 수있는 방법이 있습니까?

내 말은, 다음과 같습니다.

   ...
   .where("array", "isSimilar", yourArray)
   .get()

그래서 배열이있는 모든 문서를 얻습니다.

[10, 13.1, 0, -10]

또는 유일한 방법은 모든 문서를 다운로드하는 것입니다. 정말 느릴 수있는 문서를 다운로드 한 다음 가장 유사한 문서를 반복하고 검색하는 것입니까? "유사한 포인트 위치", "유사한 체중 감량 주", ...에 대해 이야기 할 때 정말 흥미로울 수 있다고 생각합니다.

감사.

답변

3 JayCodist Aug 16 2020 at 09:20

현재 Firestore는 이러한 종류의 쿼리를 지원하지 않습니다. 따라서 배열 비교를 위해 문자열 필드를 포함하도록 구조를 업데이트하는 것이 좋습니다. 따라서 각 문서는 다음과 같습니다.

{
   array: [12, 11, 8, 9],
   arrayStr: "12,11,8,9",
   ...
}

이 구조는 doc.array.join(",")기존의 모든 문서 를 호출 하고 값을 문서에 저장하기 만하면됩니다 .

그런 다음 다음과 같이 firestore 쿼리와 비교할 수 있습니다.

const arrToCompare = [12, 11, 8, 9];
const snapshot = await firestore().collection(collection).where("arrayStr", "==", arrToCompare.join(",")).get();
...

업데이트 : 동등성 대신 유사성으로 비교하려면 가능한 접근 방식은 arrayStr생성 중에 필드에 "유사성"논리를 적용하는 것 입니다. 예를 들어 0.5 미만의 차이를 허용하려면 Math.round()문자열로 저장하기 전에 배열 요소에 사용할 수 있습니다 . 이렇게 :

const array = [12.2, 10.7, 8.111, 9.0];
const arrayStr = array.map(num => Math.round(num)).join(","); //"12,11,8,9"

그런 다음 다음과 같이 쿼리합니다.

const arrToCompare = [12, 11, 8, 9];
const snapshot = await firestore().collection(collection).where("arrayStr", "==", arrToCompare.map(num => Math.round(num)).join(",")).get();
// Results would include arrays like [12.2, 10.7, 8.111, 9.0]
...

물론 Math.round()비교에 대한 허용 수준을 높이거나 낮추기 위해 전달되는 인수를 변경할 수 있습니다.