Firestore: 多个条件的where子句
Firestore: 多个条件的where子句
例如,我有一个动态过滤器,用于我的书籍列表,我可以设置特定的颜色、作者和类别。\n该过滤器可以同时设置多个颜色和多个类别。\n
书籍 > 红色,蓝色 > 冒险,侦探。
\n我如何有条件地添加\"where\"?\n
firebase .firestore() .collection("book") .where("category", "==", ) .where("color", "==", ) .where("author", "==", ) .orderBy("date") .get() .then(querySnapshot => {...
Firestore: 多个条件的where子句
最新的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()); });
有关此功能的文档链接在这里:[firebase.google.com/docs/firestore/query-data/queries#compound_queries](https://firebase.google.com/docs/firestore/query-data/queries#compound_queries)
为什么Google要这样做呢?基于上述`query`函数的签名,如果你想创建一个包装器以便将其替换为其他NoSQL数据库,你是无法做到的。为什么要有这样的签名呢?每个where条件都重复相同的内容。
在Firebase版本9中,文档没有涵盖到如何在查询中添加多个条件的where子句,但下面是一种方法。
通过导入`collection`、`query`和`where`函数,我们可以先创建一个空数组`queryConstraints`。然后,根据条件是否为null,将`where`子句添加到`queryConstraints`数组中。最后,使用扩展语法将`queryConstraints`数组作为参数传递给`query`函数,以实现多个条件的where子句。
这个答案的来源是一些直觉的猜测,以及我最好的朋友J-E^S^-U-S的帮助。基本上,你不需要使用任何额外的Firestore特性,而是使用JavaScript语法将参数存储在一个数组中,然后在query()的参数列表中使用扩展语法来展开数组。
以下是代码示例:
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)
通过这种方式,我们可以在Firebase版本9中实现多个条件的where子句。
Firestore: 多个条件的where子句
在API文档中可以看到,collection()方法返回一个CollectionReference。CollectionReference扩展了Query,而Query对象是不可变的。Query.where()和Query.orderBy()返回新的Query对象,这些对象在原始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调用都被简单地忽略了。这对你来说还有效吗?
这个答案还有效吗?使用`this.afs.collection('events').doc(eventID).collection('activities').doc(activityID).collection('streams')`不会返回一个扩展query的类。`afs`是什么?您使用的是AngularFire吗?如果是这样,那么所有的对象都是不同的。AF将所有内容都包装到自己的类型中。
是的,我使用的是AngularFire。该死,我需要检查他们的文档。
值得注意的是,虽然您可以通过多个where条件查询不同的属性,但您仍然不能查询相同属性的多个where条件。以您的问题为例,仍然没有解决办法可以查询`.where("category", "==", "adventure").where("category", "==", "detective")`。
我使用重新定义`query =`的解决方案,但问题是我在使用TypeScript,有没有避免使用`-ignore`的想法?
这只是主观的语法。TypeScript应该允许您重新定义变量,使用`let`来定义它们。我知道这不被推荐,因为它可能会导致由于作用域问题而引起意外行为。如果您只是想避免警告,那么`-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
注意!"您只能对单个字段执行范围(<,<=,>,>=)或不等于(!=)比较,并且在复合查询中最多可以包含一个array-contains或array-contains-any子句" firebase.google.com/docs/firestore/query-data/…
如何在Web v9中实现这个功能?
实际上,您可以对同一字段进行多个where查询:.where('category', 'in', ['adventure', 'detective'])
- firebase.google.com/docs/firestore/query-data/…
我改变了立场,我猜Firestore最终添加了这个功能!以后有机会再试试Firestore 🙂