programing

Cloud Firestore에서 논리적 OR을 사용하여 복합 쿼리를 수행하는 방법은 무엇입니까?

muds 2023. 6. 20. 21:51
반응형

Cloud Firestore에서 논리적 OR을 사용하여 복합 쿼리를 수행하는 방법은 무엇입니까?

문서에서:

또한 여러 where() 메서드를 체인으로 연결하여 보다 구체적인 쿼리(논리 AND)를 만들 수 있습니다.

▁?▁▁i▁▁how 어떻게 해야 하나요?OR 리쿼? 예:

  1. .status이라openORupcoming
  2. .status == openORcreatedAt <= <somedatetime>

OR서버가 확장하기 어렵기 때문에 지원되지 않습니다(상태를 유지하여 중복제거).해결 방법은 각 조건별로 하나씩 2개의 쿼리를 발행하고 클라이언트에 중복 적용하는 것입니다.


편집(2019년 11월):

에Cloud Firestore에서 지원합니다.INOR질의하다

위의 예에서는 다음을 수행할 수 있습니다.

// 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" 절의 일부가 아닌 모든 값에 대해 계산합니다.

예를 들어, 첫 번째 원하는 쿼리를 생각해 보십시오.

  1. 필드 상태가 열려 있거나 예정된 모든 문서 제공

다음을 분할하여 이 작업을 수행할 수 있습니다.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

반응형