Firestore: 多个条件的where子句

12 浏览
0 Comments

Firestore: 多个条件的where子句

例如,我有一个动态过滤器,用于我的书籍列表,我可以设置特定的颜色、作者和类别。\n该过滤器可以同时设置多个颜色和多个类别。\n

   书籍 > 红色,蓝色 > 冒险,侦探。

\n我如何有条件地添加\"where\"?\n

  firebase
    .firestore()
    .collection("book")
    .where("category", "==", )
    .where("color", "==", )
    .where("author", "==", )
    .orderBy("date")
    .get()
    .then(querySnapshot => {...

0
0 Comments

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条件都重复相同的内容。

0
0 Comments

在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子句。

0
0 Comments

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 🙂

0