Firestore:多个“数组包含”

时间:2018-10-16 14:23:06

标签: javascript firebase google-cloud-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']

我想搜索sku4sku2,如果找到返回对象。

我的问题是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);

不返回任何值,我相信array-contains不能与array比较,也许只有字符串/数字/布尔值?

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

谢谢

4 个答案:

答案 0 :(得分:6)

一种解决方案是将“标签”存储在对象中作为其属性名称。 node_sku = { "sku1": true, "sku2": true, ... "skun": true }

然后,您可以创建AND WHERE子句,如下所示: list.forEach( (val) => { ref = ref.where(`node_sku.${val}` , '==' , true); });

这种方法是对“无需单独查询”的问题的答案。但是,一旦您想要排序和分页,就会遇到另一个复合索引的不可见砖墙。

答案 1 :(得分:4)

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

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

Firestore - Array contains any

答案 2 :(得分:2)

如您所见,查询中只能有一个array-contains操作。当前不支持允许多个的想法,但可能是有效的。因此,我建议您file a feature request

我现在可以想到的唯一解决方案是同时包含这些组合。因此,如果要允许测试两个SKU的存在,则可以爆炸该数组以包含每个组合(按字典顺序合并键):

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

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

答案 3 :(得分:0)

使用这样的东西:

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