我正在尝试使用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']
我想搜索sku4
和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);
不返回任何值,我相信array-contains不能与array比较,也许只有字符串/数字/布尔值?
有人知道解决方案而不必单独查询吗?
谢谢
答案 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);
答案 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) );