programing

여러 값에 대한 Firestore 검색 배열 포함

iphone6s 2023. 6. 6. 00:36
반응형

여러 값에 대한 Firestore 검색 배열 포함

다음과 같은 단순 컬렉션이 있는 경우:

Fruits:
  Banana:
   title: "Banana"
   vitamins: ["potassium","B6","C"]
  Apple:
   title: "Apple"
   vitamins: ["A","B6","C"]

그리고 만약 제가 비타민 B6가 함유된 과일을 찾고 싶다면, 저는 다음을 할 것입니다.

db.collection("Fruits").whereField("vitamins", arrayContains: "A").getDocuments() { (querySnapshot, err)  in
        if let err = err {
            print("Error getting documents: \(err)")
        } else {
            for document in querySnapshot!.documents {
                print("\(document.documentID) => \(document.data())")
            }
        }
    }

그러면 제 컬렉션에 있는 모든 과일에 비타민 A가 들어있는 것을 볼 수 있을 것입니다.하지만, 비타민 B6와 C와 같은 여러 가지 비타민이 들어 있는 과일을 어떻게 검색할 수 있을까요? 단히검색수없다니습할순▁search▁simply를 검색할 수 없습니다.["B6","C"]독립적인 문자열이 아닌 배열을 찾는 것이기 때문입니다.

Cloud Firestore에서 이것이 가능합니까?그렇지 않다면 이것을 할 수 있는 다른 방법이 있습니까?

쿼리의 조건을 체인으로 연결하여 여러 조건과 일치하는 문서를 찾는 것이 좋습니다.

db.collection("Fruits")
    .whereField("vitamins", arrayContains: "B6")
    .whereField("vitamins", arrayContains: "C")

그러나 복합 쿼리에 대한 설명서는 현재 단일 쿼리에 여러 arrayContains 조건을 포함할 수 없음을 시사합니다.

그래서, 그것은 당신이 오늘 가지고 있는 것으로는 불가능합니다.배열 대신 지도 구조를 사용하는 것을 고려해 보십시오.

Fruits:
  Banana:
   title: "Banana"
   vitamins: {
     "potassium": true,
     "B6": true,
     "C": true
   }

그런 다음 다음과 같이 쿼리할 수 있습니다.

db.collection("Fruits")
    .whereField("vitamins.B6", isEqualTo: true)
    .whereField("vitamins.C", isEqualTo: true)

Firestore는 whereIn, arrayContains 및 arrayContains를 소개했습니다.2019년 말에 어떤 방법이든.이러한 방법은 논리적 'OR' 쿼리를 수행하지만 전달할 수 있는 조항은 10개로 제한됩니다(따라서 검색할 수 있는 비타민은 최대 10개).

일부 솔루션에서는 이미 데이터 재구성에 대해 언급했습니다.재구성 접근 방식을 활용하는 또 다른 해결책은 비타민을 과일 문서에 포함시키지 않고 반대로 포함시키는 것입니다.이렇게 하면 '바나나'가 포함된 모든 문서를 얻을 수 있습니다.

let vitaminsRef = db.collection('Vitamins').where('fruits', arrayContains: 'banana');

이 솔루션을 사용하면 10개 조항의 제한을 피할 수 있습니다.'과일' 배열에 '바나나'가 있는 모든 '비타민' 문서를 한 번의 읽기 작업으로 가져옵니다(너무 많으면 페이지 번호를 생각해 보십시오).

Firestore에서 어레이가 포함된 여러 쿼리를 수행할 수 없습니다.하지만, 당신은 가능한 한 많이 결합할 수 있습니다.where다음을 따라서 다음 사항을 고려해야 합니다.

[Fruits]
    <Banana>
        title: "Banana"
        vitamins:
            potassium: true
            b6: true
            c: true

Firestore.firestore().collection("Fruits").whereField("vitamins.potassium", isEqualTo: true).whereField("vitamins.b6", isEqualTo: true)

하지만, 이것은 여전히 청소를 허용하지 않습니다.OR서치. 묻기 .과일에 비타민-x나 비타민-y를 묻기 위해서는 좀 더 창의적이어야 합니다.또한 가능한 값이 많아 복합 쿼리와 결합해야 하는 경우에는 이 접근 방식을 사용하면 안 됩니다.이는 Firestore가 200개 이상의 복합 지수를 허용하지 않기 때문이며 각 복합 지수는 정확한 비타민을 지정해야 합니다.즉, 다음에 대한 개별 복합 인덱스를 만들어야 합니다.vitamins.b6,vitamins.potassium등등 그리고 당신은 총 200개 밖에 가지고 있지 않습니다.

Firestore에서 둘 이상의 Firestore 데이터베이스를 쿼리할 수 없습니다.arrayContains둘 이상을 사용할 경우 다음과 같은 오류가 발생할 수 있습니다.

잘못된 쿼리입니다.쿼리는 단일 어레이 포함 필터만 지원합니다.

둘 이상의 비타민을 필터링해야 하는 경우, 보유하고 있는 각 비타민에 대한 속성을 만든 다음 연결함으로써 데이터베이스를 구성하는 논리를 변경해야 합니다..whereField()함수 호출약간 이상하게 들리겠지만 클라우드 파이어스토어는 이렇게 작동합니다.

스키마는 다음과 같아야 합니다.

vitamins: { 
    "potassium": true,
    "B6": true,
    "C": true
}

모든 과일을 찾기 위해서는potassium,B6그리고.C비타민, 당신은 다음과 같은 질문을 사용해야 합니다:

let fruitsRef = db.collection("Fruits")
    .whereField("vitamins.potassium", isEqualTo: true)
    .whereField("vitamins.B6", isEqualTo: true)
    .whereField("vitamins.C", isEqualTo: true)

설명은 했지만 복합 인덱스 수가 200개로 빠르게 제한되기 때문에 쿼리에서 복합 인덱스를 만들어야 하는 경우에는 허용된 답변을 사용할 수 없습니다.진부하지만, 제가 생각할 수 있는 가장 좋은 해결책은 어떤 종류의 보장된 순서로, 예를 들어 알파벳 순으로, 주어진 과일에 대한 모든 비타민 조합의 배열을 저장하는 것입니다. 각 조합은 끈으로 연결됩니다.예를 들어, 바나나가 B6, C, 그리고 칼륨을 포함하고 있기 때문에, 바나나를 위한 비타민 조합은 다음과 같습니다.

  • B6
  • B6||C
  • B6||C||potassium
  • B6||potassium
  • C
  • C||potassium
  • potassium

그런 다음 사용자가 B6와 칼륨이 모두 포함된 모든 과일을 검색하는 경우 다음과 같은 질문을 할 수 있습니다.

db.collection("Fruits").where("vitamins", "array-contains", "B6||potassium")

지도 값에 대한 모든 인덱스를 만들지 않고 잘 작동하는 방법을 찾은 것 같습니다.

값 배열에서 가능한 모든 배열 조합을 생성하는 경우

[a, b] => [[a],[b],[a,b]]

쉼표나 다른 구분 기호를 사용하여 이러한 구분 기호를 정렬하고 결합할 수 있습니다.

[[a],[b],[a,b]].map => ['a','b','a,b']

그런 다음 문자열 배열을 저장합니다(정렬해야 함).array-contains정렬되고 구분된 검색 조회 사용

where('possible_value_array', 'array-contains', 'a,b')

혹시 제가 놓친 게 있는지 궁금합니다.

언급URL : https://stackoverflow.com/questions/54987399/firestore-search-array-contains-for-multiple-values

반응형