여러 값에 대한 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, 그리고 칼륨을 포함하고 있기 때문에, 바나나를 위한 비타민 조합은 다음과 같습니다.
B6B6||CB6||C||potassiumB6||potassiumCC||potassiumpotassium
그런 다음 사용자가 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
'programing' 카테고리의 다른 글
| Python + Selenium WebDriver를 사용하여 쿠키를 저장하고 로드하는 방법 (0) | 2023.06.06 |
|---|---|
| 레일 위에서 루비 배우기 (0) | 2023.06.06 |
| 오류: Gdal이 설치되어 있지만 R 종속 패키지를 설치하는 동안 gdal-config를 찾을 수 없습니다. (0) | 2023.06.06 |
| 가져오기를 모의 실행하는 방법 (0) | 2023.06.06 |
| 파이썬에서 고유 ID를 생성하려면 어떻게 해야 합니까? (0) | 2023.06.06 |