Cloud Firestore에서 논리적 OR을 사용하여 복합 쿼리를 수행하는 방법은 무엇입니까?
문서에서:
또한 여러 where() 메서드를 체인으로 연결하여 보다 구체적인 쿼리(논리 AND)를 만들 수 있습니다.
▁?▁▁i▁▁how 어떻게 해야 하나요?OR
리쿼? 예:
- .
status
이라open
ORupcoming
- .
status == open
ORcreatedAt <= <somedatetime>
OR
서버가 확장하기 어렵기 때문에 지원되지 않습니다(상태를 유지하여 중복제거).해결 방법은 각 조건별로 하나씩 2개의 쿼리를 발행하고 클라이언트에 중복 적용하는 것입니다.
편집(2019년 11월):
에Cloud Firestore에서 지원합니다.IN
된 OR
질의하다
위의 예에서는 다음을 수행할 수 있습니다.
// Get all documents in 'foo' where status is open or upcmoming
db.collection('foo').where('status','in',['open','upcoming']).get()
인 것은 수 없습니다.OR
여러 필드를 포함하는 조건입니다.
최근 IN 쿼리가 추가됨에 따라 Firestore는 "논리 OR을 가진 동일한 필드에서 최대 30개의 equality 절"을 지원합니다.
(1)에 대한 가능한 해결책은 다음과 같습니다.
documents.where('status', 'in', ['open', 'upcoming']);
Firebase 가이드 참조: 연산자 쿼리 | 및
일반적인 OR 쿼리 지원은 Google I/O 2023에서 발표되었으므로 문서에 기초하여 (2)에 대한 솔루션은 다음과 같습니다.
query(collection(db, '{collection-name}'), or(
where('status', '==', 'open'),
where('createdAt', '<=', somedatetime),
));
rxjs 병합 연산자를 사용하여 두 관측치를 바인딩할 수 있습니다.여기에 예가 있습니다.
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/merge';
...
getCombinatedStatus(): Observable<any> {
return Observable.merge(this.db.collection('foo', ref => ref.where('status','==','open')).valueChanges(),
this.db.collection('foo', ref => ref.where('status','==','upcoming')).valueChanges());
}
그런 다음 위의 방법을 사용하여 새로운 관찰 가능 업데이트를 구독할 수 있습니다.
getCombinatedStatus.subscribe(results => console.log(results);
이것이 당신에게 도움이 되기를 바랍니다, 칠레에서 온 인사들!!
지위에 대한 가치도 제공할 것을 제안합니다.
전에
{ name: "a", statusValue = 10, status = 'open' }
{ name: "b", statusValue = 20, status = 'upcoming'}
{ name: "c", statusValue = 30, status = 'close'}
다음을 기준으로 쿼리할 수 있습니다.ref.where('statusValue', '<=', 20)
그렇다면 둘 다'a'
그리고.'b'
찾을 수 있습니다.
이렇게 하면 쿼리 비용과 성능을 절약할 수 있습니다.
하지만, 모든 경우를 해결하는 것은 아닙니다.
나는 "상태" 필드가 아니라 상태 관련 필드를 가지고 있으며, 요청에 따라 true 또는 false로 업데이트합니다.
{ name: "a", status_open: true, status_upcoming: false, status_closed: false}
그러나 Firebase Cloud Functions를 선택합니다.다음과 같은 상태 관련 속성을 업데이트하고 상태 변경을 수신하는 기능을 사용할 수 있습니다.
{ name: "a", status: "open", status_open: true, status_upcoming: false, status_closed: false}
하나 또는 다른 하나, 당신의 질문은 단지
...where('status_open','==',true)...
도움이 되길 바랍니다.
것은 "의 경우 "enum" 필드를 추가하여 " 수 .where("enum_<value>", "==", false)
원하는 "OR" 절의 일부가 아닌 모든 값에 대해 계산합니다.
예를 들어, 첫 번째 원하는 쿼리를 생각해 보십시오.
- 필드 상태가 열려 있거나 예정된 모든 문서 제공
다음을 분할하여 이 작업을 수행할 수 있습니다.status: string
필드로 를 지정합니다.
status_open: bool
status_upcoming: bool
status_suspended: bool
status_closed: bool
"상태가 열려 있거나 다가올 위치" 쿼리를 수행하려면 다음 작업을 수행합니다.
where("status_suspended", "==", false).where("status_closed", "==", false)
이것은 어떻게 작동합니까?음, 그것은 열거형이기 때문에, 당신은 그 값들 중 하나가 반드시 가지고 있어야 한다는 것을 알고 있습니다.true
맡겨진.따라서 지정된 항목에 대해 다른 모든 값이 일치하지 않는다고 판단할 수 있는 경우에는 원래 찾고 있던 값 중 하나와 일치해야 합니다.
참고 항목
in
/not-in
/array-contains-in
: https://firebase.google.com/docs/firestore/query-data/queries#in_and_array-contains-any
!=
: https://firebase.googleblog.com/2020/09/cloud-firestore-not-equal-queries.html
저는 모든 사람들이 그것이 불가능하다고 말하는 것을 좋아하지 않습니다.
모델에 다른 "composite" 필드를 생성하여 합성을 작성하는 경우입니다.
예를 들어, 모든 논리 또는 요소를 포함하는 각 문서에 대한 배열을 만듭니다.
그런 다음 .where("field", arrayContains: [...]를 쿼리합니다.
우리는 지금 같은 문제를 겪고 있습니다. 운 좋게도 우리의 가능한 값은 A,B,C,D(4)뿐이므로 A||B,A|C,A|B|C,D 등과 같은 것을 쿼리해야 합니다.
달 쿼리를 합니다.array-contains
우리가 입니다.
if (a) {
array addObject:@"a"
}
if (b) {
array addObject:@"b"
}
if (a||b) {
array addObject:@"a||b"
}
etc
그리고 우리는 모두를 위해 이것을 합니다.4!
값 또는 조합이 얼마나 많은지 확인할 수 있습니다.
그러면 우리는 간단히 질문을 확인할 수 있습니다.[document arrayContains:@"a||c"]
우리가 필요로 하는 조건이 무엇이든 간에.
만약에 이 되는 ,A
의 조건중의 조건(A,B,C,D)의 은 다음과 같은 문자열을 합니다.@["A", "A||B", "A||C", "A||D", "A||B||C", "A||B||D", "A||C||D", "A||B||C||D"]
그럼 그 중 하나라도OR
하면 됩니다.array-contains
예 C") "A||C")
참고: 이 방법은 OR을 비교할 수 있는 가능한 값이 몇 개 있는 경우에만 합리적인 방법입니다.
기본 문서를 처음 사용하는 경우이므로 어레이에 대한 자세한 내용은 여기를 참조하십시오.
필드 수가 제한된 경우 위의 예와 같이 true 및 false를 사용하여 새 필드를 만듭니다.그러나 런타임까지 필드가 무엇인지 모르는 경우에는 쿼리만 결합하면 됩니다.
다음은 태그 또는 예제입니다.
// the ids of students in class
const students = [studentID1, studentID2,...];
// get all docs where student.studentID1 = true
const results = this.afs.collection('classes',
ref => ref.where(`students.${students[0]}`, '==', true)
).valueChanges({ idField: 'id' }).pipe(
switchMap((r: any) => {
// get all docs where student.studentID2...studentIDX = true
const docs = students.slice(1).map(
(student: any) => this.afs.collection('classes',
ref => ref.where(`students.${student}`, '==', true)
).valueChanges({ idField: 'id' })
);
return combineLatest(docs).pipe(
// combine results by reducing array
map((a: any[]) => {
const g: [] = a.reduce(
(acc: any[], cur: any) => acc.concat(cur)
).concat(r);
// filter out duplicates by 'id' field
return g.filter(
(b: any, n: number, a: any[]) => a.findIndex(
(v: any) => v.id === b.id) === n
);
}),
);
})
);
안타깝게도 10개 이상의 항목을 결합할 수 있는 다른 방법은 없습니다(10개 미만의 항목일 경우 어레이 포함-any 사용).
또한 검색에서 일치할 ID 필드를 모르기 때문에 중복 읽기를 방지할 수 있는 다른 방법이 없습니다.다행히도, 파이어베이스는 좋은 캐싱을 가지고 있습니다.
약속을 좋아하시는 분들은...
const p = await results.pipe(take(1)).toPromise();
이에 대한 자세한 내용은 제가 작성한 이 기사를 참조하십시오.
J
파이어베이스는 2023년에 OR 조항을 도입했습니다.
모듈식 웹 예제:
const q = query(
collection(db, "collection_name"),
or(
where('status', '==', 'open'),
where('createdAt', '<=', Timestamp.fromDate(new Date()))
)
);
결합이 가능합니다.AND
와 함께OR
절:
const q = query(
collection(db, "cities"),
and(
where('state', '==', 'CA'),
or(
where('capital', '==', true),
where('population', '>=', 1000000)
)
));
OR은 지원되지 않습니다.
하지만 당신이 필요하다면 당신의 코드로 할 수 있습니다.
예: 쿼리 제품을 원하는 경우(Size Equal Xl 또는 XXL: AND Gender는 남성)
productsCollectionRef
//1* first get query where can firestore handle it
.whereEqualTo("gender", "Male")
.addSnapshotListener((queryDocumentSnapshots, e) -> {
if (queryDocumentSnapshots == null)
return;
List<Product> productList = new ArrayList<>();
for (DocumentSnapshot snapshot : queryDocumentSnapshots.getDocuments()) {
Product product = snapshot.toObject(Product.class);
//2* then check your query OR Condition because firestore just support AND Condition
if (product.getSize().equals("XL") || product.getSize().equals("XXL"))
productList.add(product);
}
liveData.setValue(productList);
});
Float dart 언어의 경우 다음을 사용합니다.
db.collection("projects").where("status", whereIn: ["public", "unlisted", "secret"]);
실제로 저는 @Dan McGrath가 여기서 일하는 것이 그의 대답을 다시 쓴다는 것을 발견했습니다.
private void query() {
FirebaseFirestore db = FirebaseFirestore.getInstance();
db.collection("STATUS")
.whereIn("status", Arrays.asList("open", "upcoming")) // you can add up to 10 different values like : Arrays.asList("open", "upcoming", "Pending", "In Progress", ...)
.addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(@Nullable QuerySnapshot queryDocumentSnapshots, @Nullable FirebaseFirestoreException e) {
for (DocumentSnapshot documentSnapshot : queryDocumentSnapshots) {
// I assume you have a model class called MyStatus
MyStatus status= documentSnapshot.toObject(MyStatus.class);
if (status!= null) {
//do somthing...!
}
}
}
});
}
언급URL : https://stackoverflow.com/questions/46632042/how-to-perform-compound-queries-with-logical-or-in-cloud-firestore
'programing' 카테고리의 다른 글
단일 파일에서 충돌 해결 다시 시작/실행 취소 (0) | 2023.06.20 |
---|---|
Spring @Import 또는 @Configuration을 매개변수로 설정할 수 있습니까? (0) | 2023.06.20 |
레포의 원격 깃 주소를 검색하려면 어떻게 해야 합니까? (0) | 2023.06.20 |
URL 문자열에서 포트 번호를 제거하는 방법 (0) | 2023.06.20 |
Windows 환경에서 현재 사용자를 어떻게 찾습니까? (0) | 2023.06.15 |