Firestore:多个“数组包含”

IT技术 javascript firebase google-cloud-firestore
2021-03-12 08:48:02

关于这个问题的更新

Firestore 推出了另一个类似于 in 查询的功能,即 array-contains-any 查询。此功能允许您同时对多个值执行包含数组的查询。

使用 array-contains-any 运算符将同一字段上的最多 10 个 array-contains 子句与逻辑 OR 组合在一起。array-contains-any 查询返回给定字段是包含一个或多个比较值的数组的文档:

ref = ref.where('node_sku' , 'array-contains-any' , list);

Firestore - 数组包含任何

问题

我正在尝试where()使用array-contains运算符通过多种方法过滤数据,但是出现以下错误:

An error occured: Error: 3 INVALID_ARGUMENT: 
A maximum of 1 'ARRAY_CONTAINS' filter is allowed.

基本上,我有一个包含以下文档的集合:

product1 
  - node_sku ['sku1', 'sku2', 'sku3' ]

product2 
  - node_sku ['sku4', 'sku5', 'sku6' ]

然后我的数组包含我希望在数据库中找到的项目:

const list = ['sku4', 'sku2']

我想搜索sku4and sku2,如果找到任何返回对象。

我的问题是array-contains不允许运行多次。

这是我用来过滤的代码:

const list = ['sku4', 'sku2'];


let database = firestore_db.collection('glasses');
let ref = database;

list.forEach( (val) => { 
    ref = ref.where('node_sku' , 'array-contains' , val);
});
ref.get() 
.then( (snapshot) => glassesRequestComplete(snapshot, req, response))
.catch( (error) => glassesRequestError(error, response) );

正如您所注意到的,我的问题是我正在遍历我的list数组,但是我ref抛出了一个错误,因为我不止一次触发“数组包含”。

我还尝试与数组进行比较:

ref.where('node_sku' , 'array-contains' , list);

它不返回 any ,我相信 array-contains 不与数组进行比较,可能只有字符串/数字/布尔值?

有人知道解决方案而不必单独查询吗?

谢谢

4个回答

一种解决方案是将“标签”作为其属性名称存储在对象中。

node_sku = {
  "sku1": true,
  "sku2": true,
  ...
  "skun": true
}

然后你可以像这样创建 AND WHERE 子句:

list.forEach( (val) => { 
  ref = ref.where(`node_sku.${val}` , '==' , true);
});

这种方法是对“无需单独查询它们”这一问题的回答。然而,一旦你想要排序和分页,你就会遇到另一个复合索引的无形砖墙。

正如您发现array-contains的那样,查询中只能有一个操作。目前不支持允许多个的想法,但可能是有效的。所以我建议你提交一个功能请求

我现在可以为您的用例想到的唯一解决方案是还包括组合。因此,如果您想允许测试现有的两个 SKU,您可以分解数组以包含每个组合(按字典顺序合并键):

product1 
  - node_sku ['sku1', 'sku2', 'sku3', 'sku1_sku2', 'sku1_sku3', 'sku2_sku3' ]

对于两个来说,这可能仍然是合理的,但组合爆炸将使其变得不可行。

我的问题是我有数千个 sku,这将使我无法创建它,因为所有组合都太长了。我觉得每次遇到 Firebase 的问题就像用我的头撞墙。我会向他们提出要求。你一如既往的乐于助人!谢谢弗兰克
2021-04-20 08:48:02

Firestore 推出了另一个类似于 in 查询的功能,即 array-contains-any 查询。此功能允许您同时对多个值执行包含数组的查询。

ref = ref.where('node_sku' , 'array-contains-any' , list);

Firestore - 数组包含任何

我认为解决了这个问题: val cityRef = db.collection("cities") cityRef.whereIn("country", listOf("USA", "Japan"))
2021-04-20 08:48:02
感谢您发布此信息。我已经根据您的链接和评论更新了我的问题。
2021-05-05 08:48:02

使用这样的东西:

ref.where("node_sku", "in", list).get()
.then((snapshot) => glassesRequestComplete(snapshot, req, response)).catch( (error) => glassesRequestError(error, response) );