例如,我的图书列表有动态过滤器,我可以在其中设置特定的颜色、作者和类别。 这个过滤器可以一次设置多种颜色和多个类别。
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,并且 Query 对象是不可变的。 Query.where() 和 Query.orderBy() 返回新的 Query 对象,这些对象在原始 Query(保持未修改)之上添加操作。您将不得不编写代码来记住这些新的 Query 对象,以便您可以继续对它们进行链式调用。所以,你可以像这样重写你的代码:
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(...)
}
Firebase 版本 9
docs 没有涵盖这一点,但这里是如何向查询添加条件 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的一些直观猜测和帮助
您可以使用多个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
操作。
如果你使用角射,你可以像这样使用
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 子句完成),请参见here。
比如有一个数组是这样的
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());
});
});
由于
CollectionRef
在 firebase web 版本 9 中没有 query
方法,
我修改了@abk的回答
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);
});