在 JavaScript 中动态添加属性到数据库查询

问题描述 投票:0回答:2

我正在编写一个函数来查询 Firestore 数据库集合中仅具有某些属性的文档。过滤器被定义为“键、值”对的数组。 例如:

[
  ["Colour", "green"],
  ["Colour", "blue"],
  ["Greeting", "hello"]
]

该数组可以是任意长度,我正在尝试获取数据库中没有过滤器数组中列出的值的每个文档。

我可以通过使用来做到这一点:

await db.collection("database")
  .where("Colour", "!=", "blue")
  .where("Colour", "!=", "green")
  .where("Greeting", "!=", "hello")
  .get()

我的问题是过滤器可以是任意长度,因此我无法编写具有一定数量的

.where()
方法的查询。 JavaScript 中是否有任何方法可以动态地将方法添加到查询中,如上所示(不知道我需要添加多少个方法)?

我现在的解决方法是查询整个数据库,然后使用 Javascript 过滤器函数对其进行排序,但我只想查询数据库以获取所需的值。

或者,是否有任何其他 Firestore 查询可以完成此过滤器?我正在查看 docs,但是我的过滤器设置为可能重复或未定义的键/值对,似乎任何复杂的查询方法都不起作用。

javascript database firebase google-cloud-firestore nosql
2个回答
3
投票

假设您正在构建一个仅包含排除的键值对的数组,并且排除的值已正确索引,我们可以开始定义一些常量:

const collectionRef = db.collection("database");

const excludedKeyValuePairs = [
  ["Colour", "green"],
  ["Colour", "blue"],
  ["Greeting", "hello"],
]

现在我们有了这些,我们可以使用 Array#reduce 构建查询。

const query = excludedKeyValuePairs
  .reduce(
    (query, [key, value]) => query.where(key, "!=", value), // appends the new constraint, returning the new query object
    collectionRef
  );

const querySnapshot = await query.get();

但是,如果您可以使用较新的模块化 Firestore SDK,您也可以使用以下方法实现相同的结果:

import { getFirestore, getDocs, collection, query, where } from "firebase/firestore";

const db = getFirestore();
const collectionRef = collection(db, "database");
const constraints = [
  where("Colour", "!=", "green"),
  where("Colour", "!=", "blue"),
  where("Greeting", "!=", "Hello")
  // elements can also be added or removed using standard array methods as needed.
]
// OR const constraints = excludedKeyValuePairs.map(([key, value]) => where(key, "!=", value))

const querySnapshot = await getDocs(query(collectionRef, ...constraints));

2
投票

您可以使用以下方法将条件数组映射到 where 子句:

const exclusions = [
  ["Colour", "green"],
  ["Colour", "blue"],
  ["Greeting", "hello"],
]

let collectionRef = db.collection("database");
const conditions = exclusions.map((e) => where(e[0], "!=", e[1]));
// spread conditions array
let query = query(collectRef, ...conditions);

const querySnapshot = await getDocs(query);
© www.soinside.com 2019 - 2024. All rights reserved.