Firestore:多个条件 where 子句
Posted
技术标签:
【中文标题】Firestore:多个条件 where 子句【英文标题】:Firestore: Multiple conditional where clauses 【发布时间】:2018-06-10 17:49:40 【问题描述】:例如,我为我的书籍列表设置了动态过滤器,我可以在其中设置特定的颜色、作者和类别。 此过滤器可以一次设置多种颜色和多个类别。
Book > Red, Blue > Adventure, Detective.
如何有条件地添加“where”?
firebase
.firestore()
.collection("book")
.where("category", "==", )
.where("color", "==", )
.where("author", "==", )
.orderBy("date")
.get()
.then(querySnapshot => ...
【问题讨论】:
【参考方案1】:正如您在 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(...)
【讨论】:
编辑:它有效,当您重新分配query =
时,我错过了... - 这对我不起作用。所有的 where 调用都被简单地忽略了。这仍然对您有用吗?
@JimmyKane afs
是什么?你在使用 AngularFire 吗?如果是这样,那么您的所有对象都是不同的。 AF 将所有内容包装到自己的类型中。
需要注意的是,虽然可以查询多个不同属性的where,但仍然不能查询同一属性的多个where。以您的问题为例,查询.where("category", "==", "adventure").where("category", "==", "detective")
仍然有no解决方案
@pikilon 这只是固执己见的语法。 Typescript 应该允许您重新定义变量,使用let
来定义它们。我知道不建议这样做,因为它可能由于范围问题而导致意外行为。如果您只是想避免警告,@ts-ignore
就可以了。想到的另一件事是将每个新结果推入一个数组:const queries = [firebase.firestore().collection("book")]; queries.push(queries[queries.length - 1].where(...)); queries[queries.length - 1].get().then(...)
。或者你可以写一个包装类......选择你的毒药;-)
您现在可以使用 IN 运算符:firebase.google.com/docs/firestore/query-data/queries【参考方案2】:
除了@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);
【讨论】:
【参考方案3】:使用 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());
);
【讨论】:
是否有相关文档的链接? @m.spyratos 这里是文档链接firebase.google.com/docs/firestore/query-data/…【参考方案4】: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 的一些直觉猜测和帮助
【讨论】:
【参考方案5】:例如,有一个数组是这样的
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
您将获得集合集查询的条件。
【讨论】:
【参考方案6】:如果你使用的是角火,你可以像这样使用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。
【讨论】:
【参考方案7】: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());
);
);
【讨论】:
【参考方案8】:请注意,多个WHERE
子句本质上是AND
操作。
【讨论】:
以上是关于Firestore:多个条件 where 子句的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Firestore 7.24.0 实例中查询具有多个 where 子句的数据?
iOS - Firestore 复合索引中的索引上的多个 orderBy 和 where 子句