Firestore:多个“数组包含”

Posted

技术标签:

【中文标题】Firestore:多个“数组包含”【英文标题】:Firestore: Multiple 'array-contains' 【发布时间】:2019-03-21 02:52:14 【问题描述】:

关于这个问题的更新

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 - Array contains any

问题

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

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 抛出了一个错误,因为我不止一次触发了“array-contains”。

我也尝试过与数组进行比较:

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

不返回任何,我相信数组包含不与数组比较,可能只有字符串/数字/布尔值?

有没有人知道无需单独查询的解决方案?

谢谢

【问题讨论】:

【参考方案1】:

使用这样的东西:

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

【讨论】:

【参考方案2】:

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

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

Firestore - Array contains any

【讨论】:

感谢您发布此信息。我已根据您的链接和 cmets 更新了我的问题。 我认为可以解决问题:val citiesRef = db.collection("cities") urbanRef.whereIn("country", listOf("USA", "Japan"))【参考方案3】:

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

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

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

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

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

【讨论】:

【参考方案4】:

如您所见,查询中只能有一个 array-contains 操作。目前不支持允许多个的想法,但可能是有效的。所以我推荐你file a feature request。

我现在能想到的针对您的用例的唯一解决方案是同时包含这些组合。因此,如果您想允许测试两个 SKU 的存在,您可以展开数组以包含每个组合(按字典顺序合并键):

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

对于两个可能仍然是合理的,但组合爆炸将使它不可行。

【讨论】:

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

以上是关于Firestore:多个“数组包含”的主要内容,如果未能解决你的问题,请参考以下文章

Firebase Firestore - 使用多个“数组包含”过滤数据

如何在 Firestore 中一次创建/更新多个文档

使用python在Firestore中运行GeoPoint

在 Firestore 中自动创建集合

如何从firestore的路径中获取布尔值

如何为 Firestore 创建大量示例数据?