소방서:다중 조건부 where 절
예를 들어 특정 색상, 작가 및 범주를 설정할 수 있는 동적 필터가 있습니다.이 필터는 여러 색상과 여러 범주를 동시에 설정할 수 있습니다.
   Book > Red, Blue > Adventure, Detective.
 
조건부로 "where"를 추가하려면 어떻게 해야 합니까?
  firebase
    .firestore()
    .collection("book")
    .where("category", "==", )
    .where("color", "==", )
    .where("author", "==", )
    .orderBy("date")
    .get()
    .then(querySnapshot => {...
API 문서에서 볼 수 있듯이 collection() 메서드는 CollectionReference를 반환합니다.CollectionReference는 쿼리를 확장하며 쿼리 개체는 변경할 수 없습니다.Query.where() 및 Query.orderBy()는 원래 쿼리 위에 작업을 추가하는 새 쿼리 개체를 반환합니다(수정되지 않은 상태로 유지됨).이러한 새 쿼리 개체를 기억하려면 코드를 작성해야 계속해서 호출을 체인으로 연결할 수 있습니다.따라서 코드를 다음과 같이 다시 작성할 수 있습니다.
var query = firebase.firestore().collection("book")
query = query.where(...)
query = query.where(...)
query = query.where(...)
query = query.orderBy(...)
query.get().then(...)
 
이제 각 단계에서 적용할 필터를 결정하기 위해 조건을 입력할 수 있습니다.재할당만query각 필터가 새로 추가됩니다.
if (some_condition) {
    query = query.where(...)
}
파이어베이스 버전 9
문서에서는 이 문제를 다루지 않지만 여기에 쿼리에 조건부 where 절을 추가하는 방법이 있습니다.
import { collection, query, where } from 'firebase/firestore'
const queryConstraints = []
if (group != null) queryConstraints.push(where('group', '==', group))
if (pro != null) queryConstraints.push(where('pro', '==', pro))
const q = query(collection(db, 'videos'), ...queryConstraints)
 
이 대답의 출처는 약간의 직관적인 추측과 나의 가장 친한 친구 J-E^S^-U-S의 도움입니다.
Firebase 버전 9(2022년 1월 업데이트):
여러 where 절을 사용하여 데이터를 필터링할 수 있습니다.
import { query, collection, where, getDocs } from "firebase/firestore";
const q = query(
  collection(db, "products"),
  where("category", "==", "Computer"),
  where("types", "array-contains", ['Laptop', 'Lenovo', 'Intel']),
  where("price", "<=", 1000),
);
const docsSnap = await getDocs(q);
    
docsSnap.forEach((doc) => {
  console.log(doc.data());
});
@Doug Stevenson이 대답하는 것 외에도.두 개 이상이 있을 때where제 경우처럼 좀 더 역동적으로 만드는 것이 필요합니다. 
function readDocuments(collection, options = {}) {
    let {where, orderBy, limit} = options;
    let query = firebase.firestore().collection(collection);
    if (where) {
        if (where[0] instanceof Array) {
            // It's an array of array
            for (let w of where) {
                query = query.where(...w);
            }
        } else {
            query = query.where(...where);
        }
    }
    if (orderBy) {
        query = query.orderBy(...orderBy);
    }
    if (limit) {
        query = query.limit(limit);
    }
    return query
            .get()
            .then()
            .catch()
    }
// Usage
// Multiple where
let options = {where: [["category", "==", "someCategory"], ["color", "==", "red"], ["author", "==", "Sam"]], orderBy: ["date", "desc"]};
//OR
// A single where
let options = {where: ["category", "==", "someCategory"]};
let documents = readDocuments("books", options);
참고로 배수입니다.WHERE절은 본질적으로AND작동.
예를 들어, 다음과 같은 배열이 있습니다.
const conditionList = [
  {
    key: 'anyField',
    operator: '==',
    value: 'any value',
  },
  {
    key: 'anyField',
    operator: '>',
    value: 'any value',
  },
  {
    key: 'anyField',
    operator: '<',
    value: 'any value',
  },
  {
    key: 'anyField',
    operator: '==',
    value: 'any value',
  },
  {
    key: 'anyField',
    operator: '==',
    value: 'any value',
  },
]
 
그런 다음 쿼리 조건을 설정할 컬렉션을 이 함수에 넣으면 됩니다.
function* multipleWhere(
  collection,
  conditions = [{ field: '[doc].[field name]', operator: '==', value: '[any value]' }],
) {
  const pop = conditions.pop()
  if (pop) {
    yield* multipleWhere(
      collection.where(pop.key, pop.operator, pop.value),
      conditions,
    )
  }
  yield collection
}
 
컬렉션 집합 쿼리의 조건을 얻을 수 있습니다.
async yourFunction(){
    const Ref0 = firebase.firestore().collection("your_collection").doc(doc.id)
    const Ref1 = appointmentsRef.where('val1', '==',condition1).get();
    const Ref2 = appointmentsRef.where("val2", "!=", condition2).get()
    const [snapshot_val1, snapshot_val2] = await Promise.all([Ref1, Ref2]);
    
    const val1_Array = snapshot_val1.docs;
    const val2_Array = snapshot_val2.docs;
    const globale_val_Array = val1_Array .concat(val2_Array );
    return globale_val_Array ;
  }
/*Call you function*/
this.checkCurrentAppointment().then(docSnapshot=> {
      docSnapshot.forEach(doc=> {
          console.log("Your data with multiple code query:", doc.data());
      });
    });
각진 불을 사용하는 경우에는 그냥 사용할 수 있습니다.reduce이와 같이:
const students = [studentID, studentID2,...];
this.afs.collection('classes',
  (ref: any) => students.reduce(
    (r: any, student: any) => r.where(`students.${student}`, '==', true)
    , ref)
).valueChanges({ idField: 'id' });
 
다음은 여러 태그의 예입니다.
비각형 프레임 워크에 대해 이 값을 쉽게 변경할 수 있습니다.
OR 쿼리(복수의 where 절로는 수행할 수 없음)는 여기를 참조하십시오.
~하듯이CollectionRef을 가지고 있지 않음query파이어베이스 웹 버전 9의 방법,
async getQueryResult(path, options = {}) {
    /* Example
    options = {
      where: [
        ["isPublic", "==", true],
        ["isDeleted", "==", false]
      ],
      orderBy: [
        ["likes"],
        ["title", "desc"]
      ],
      limit: 30
    }
    */
    try {
      let { where, orderBy, limit } = options;
      let collectionRef = collection(<firestore>, path);
      let queryConstraints = [];
      if (where) {
        where = where.map((w) => firestore.where(...w));
        queryConstraints = [...queryConstraints, ...where];
      }
      if (orderBy) {
        orderBy = orderBy.map((o) => firestore.orderBy(...o));
        queryConstraints = [...queryConstraints, ...orderBy];
      }
      if (limit) {
        limit = firestore.limit(limit);
        queryConstraints = [...queryConstraints, limit];
      }
      const query = firestore.query(collectionRef, ...queryConstraints);
      const querySnapshot = await firestore.getDocs(query);
      const docList = querySnapshot.docs.map((doc) => {
        const data = doc.data();
        return {
          id: doc.id,
          ...data,
        };
      });
      return docList;
    } catch (error) {
      console.log(error);
    }
  }
전달하고 문서를 가져올 수 있는 필터의 경로와 배열을 지정할 수 있는 간단한 기능입니다.
async function filterDoc(path, filters) {
  if (!path) return [];
  //define the collection path
  let q = db.collection(path);
  //check if there are any filters and add them to the query
  if (filters.length > 0) {
    filters.forEach((filter) => {
      q = q.where(filter.field, filter.operator, filter.value);
    });
  }
  //get the documents
  const snapshot = await q.get();
  //loop through the documents
  const data = snapshot.docs.map((doc) => doc.data());
  //return the data
  return data;
}
//call the function
const data = await filterDoc(
  "categories_collection",
  [
    {
      field: "status",
      operator: "==",
      value: "active",
    },
    {
      field: "parent_id",
      operator: "==",
      value: "kSKpUc3xnKjtpyx8cMJC",
    },
  ]
);
이것은 또한 이 문제에 대한 해결책이 될 수 있습니다.
async function filterCollection(collectionName, filterArr) {
    if (!collectionName) return [];
    let query = db.collection(collectionName);
    if (filterArr.length > 0) {
        filterArr.forEach((filter) => {
            query = query.where(filter.field, filter.operator, filter.value);
        });
    }
    const snapshot = await query.get();
    const response = snapshot.docs.map((doc) => {
        return { id: doc.id, result: doc.data() }
    });
    return response;
}
  /**List the Data */
app.get("/list-documet-ids", async (req, res, next) => {
    const data = await filterCollection(
        "Users",
        [
            {
                field: "color",
                operator: "==",
                value: 'red',
            },
            {
                field: "categories",
                operator: "==",
                value: 'Detective',
            },
        ]
    );
    res.send(data);
});
언급URL : https://stackoverflow.com/questions/48036975/firestore-multiple-conditional-where-clauses
'programing' 카테고리의 다른 글
| Oracle PL/SQL에서 <, > 및 & 문자를 html 엔티티로 이스케이프하는 방법 (0) | 2023.06.20 | 
|---|---|
| Excel은 탭으로 구분된 파일을 줄 바꿈 없이 저장합니다(UNIX/Macos X). (0) | 2023.06.15 | 
| 레일 마이그레이션을 사용하여 열을 내리는 방법 (0) | 2023.06.15 | 
| TypeScript로 check i18n 사전을 타이핑하는 방법은 무엇입니까? (0) | 2023.06.15 | 
| Oracle: 방금 삽입한 행의 시퀀스 번호를 가져오려면 어떻게 해야 합니까? (0) | 2023.06.15 |