【问题标题】:Firebase Firestore: Query with logical OR and paginationFirebase Firestore:使用逻辑 OR 和分页进行查询
【发布时间】:2021-12-10 18:50:03
【问题描述】:

我知道 Firestore 查询中没有真正的逻辑“或”。这就是为什么我通常会做两个单独的查询并在客户端合并结果。

但是我现在需要添加分页。对于分页,在客户端合并来自 Firestore 的结果显然不起作用。

编辑:关于我的数据库方案的更多信息:

// Collection: 'items'
doc-id-1
   provider_id: 'ABCDE'
   company_id: 'FGHIJ'

doc-id-2
   provider_id: 'KLMNO'
   company_id: 'ABCDE'

doc-id-3
   provider_id: 'ABCDE'
   company_id: 'ABCDE'

doc-id-4
   provider_id: 'KLMNO'
   company_id: 'KLMNO'

这是我的例子:

// Get items by provider
db_query = this.db.collection('items').ref
    .where('provider_id', '==', 'ABCDE');

// OR

// Get items by company
db_query = this.db.collection('items').ref
    .where('company_id', '==', 'ABCDE');

/* 
   Combining the queries above with a logical OR should return
   the following documents (from my database scheme further up):
     - doc-id-1
     - doc-id-2
     - doc-id-3
*/

我需要组合这些查询(获取items,其中provider_id OR company_id 具有给定值)。

我的分页方式如下(Firestore 中的默认方法):

// Query type (init, next page, prev page, fallback)
if (query_type == 'init') {
  db_query = db_query.limit(limit);

} else if (query_type == 'next') {
  db_query = db_query.startAfter(last_in_response).limit(limit);

} else if (query_type == 'prev') {
  db_query = db_query.endBefore(first_in_response).limitToLast(limit);

} else {
  db_query = db_query.limit(limit);
}

有没有办法解决这个问题?如果我仍然在客户端组合结果,我的分页光标将不正确。因此,我需要以某种方式级联查询,但我找不到合适的方法。

提前感谢您的任何提示!

【问题讨论】:

  • 您是否只想合并这两个查询,即搜索 same items 集合中的所有文档,其中provider_idcompany_id 等于相同的值( ABCDE 在你的例子中)?
  • @RenaudTarnec 我添加了我的数据库方案和集合“项目”的一些示例数据。此外,我添加了一个示例,该示例记录了带有某种逻辑“OR”的查询应该返回。两个字段(provider_id 和 company_id)可以相同,但也可以不同。
  • 感谢您的更新。我已经按照您详细说明的方式理解了它,因此我的回答中提出的解决方案仍然有效! :-) 我会添加更多细节。

标签: javascript firebase google-cloud-firestore pagination


【解决方案1】:

我需要结合这些查询(获取items,其中provider_id OR company_id 具有给定值)。

在您的特定情况下(即搜索 same items 集合中的所有文档,其中 provider_idcompany_id 等于相同的值)您可以对数据进行非规范化,例如,有一个数组类型的额外字段provider_company_ids,有两个元素。第一个元素将保存provider_id 的值,第二个元素将保存company_id 的值。

那么你可以使用array-contains操作符如下:

db_query = this.db.collection('items').ref
.where("provider_company_ids", "array-contains", "ABCDE");

您将能够正确分页,因为它现在是一个单个查询。


在您的问题下添加评论后更新:

实施上述解决方案后,您的文档将如下所示:

// Collection: 'items'
doc-id-1
   provider_id: 'ABCDE'
   company_id: 'FGHIJ'
   provider_company_ids: ['ABCDE', 'FGHIJ']  // New field of type array

doc-id-2
   provider_id: 'KLMNO'
   company_id: 'ABCDE'
   provider_company_ids: ['KLMNO', 'ABCDE']

doc-id-3
   provider_id: 'ABCDE'
   company_id: 'ABCDE'
   provider_company_ids: ['ABCDE', 'ABCDE']

doc-id-4
   provider_id: 'KLMNO'
   company_id: 'KLMNO'
   provider_company_ids: ['KLMNO', 'KLMNO']

PS:我不确定您的代码 (db_query = this.db.collection('items').ref.where('provider_id', '==', 'ABCDE');) 中的 ref 属性是什么。我在我的 anwser 中重新使用它,假设this.db.collection('items').ref 返回一个Query

【讨论】:

  • 优雅的解决方案,完美运行。谢谢!
猜你喜欢
  • 1970-01-01
  • 2018-03-25
  • 2019-08-30
相关资源
最近更新 更多