【问题标题】:Firestore - Possible to query by array-not-contains?Firestore - 可以通过数组不包含查询吗?
【发布时间】:2020-01-05 00:06:13
【问题描述】:

我知道通过数组中不存在的值进行查询会非常困难,但是有没有办法做到这一点而不完全这样做?

这是我的场景 - 我有一个基于订阅的服务,人们可以选择加入并“关注”特定的艺术家。在我的后端,这将创建一个订阅文档,其中包含他们的 followerId、他们想要关注的艺术家的 id(称为 artistId)和一个称为 push 的数组。艺术家可以添加新版本,然后在未来向每个关注者发送特定歌曲的通知。我想跟踪哪个追随者被推送了哪个版本,这在前面提到的推送数组中完成。我需要一种方法来查找哪些追随者已经被推送到特定版本,所以......

我正在考虑合并两个查询,但我不确定是否可行。比如:

  1. db.collection('subscriptions').where('artistId', '==', artistId)
  2. db.collection('subscriptions').where('artistId', '==', artistId).where('pushed', 'array-contains', releaseId)

然后取两个查询结果的交集,减去第一个查询,得到未推送特定版本的关注者。

这可能吗?还是有更好的办法?

【问题讨论】:

    标签: firebase google-cloud-firestore


    【解决方案1】:

    无法在 Firestore 中查询具有特定字段或值的文档。这不是“非常困难”,但根本不可能。要详细了解为什么会这样,请参阅:

    您的解决方法是可行的,而且在技术上甚至不是很复杂。唯一要记住的是,您需要加载所有艺术家。因此,性能将与您拥有的艺术家数量成线性关系。目前这对您的应用来说可能没问题,但肯定需要对它进行一些测量。

    通常我的解决方法不是跟踪什么版本被推送给用户,而是最后一次推送被发送给用户的时间。假设一个版本有一个“通知发送时间戳”,每个用户都有一个“最后收到的通知时间戳”。通过比较两者,您可以查询尚未收到有关特定版本通知的用户。

    具体的数据模型取决于您的具体用例,您可能需要跟踪每个用户的多个时间戳(例如,他们关注的每个艺术家)。但是我发现总体上我可以根据这个模型想出一个合理的解决方案。

    【讨论】:

    • 我发现了这个:firebase.google.com/docs/reference/rules/rules.List,这可能是解决这个问题的可行方案。是否可以在查询中使用 X in Y 运算符,还是必须先从数据库中读取文档?
    • 该链接描述了安全规则中的一项操作,用于检测列表确实是否包含某个值。 SDK 中的等价物是 array-contains 运算符。
    【解决方案2】:

    对于 Elasticsearch 案例,您需要与您的数据库和 elasticsearch 服务器同步。并且还需要在你的谷歌云平台上制定防火墙规则,你需要远离对你服务器的任意请求,因为这可能会导致带宽成本。

    【讨论】:

    【解决方案3】:

    not-in 运算符现已在 Firestore 中可用!

    citiesRef.where('country', 'not-in', ['USA', 'Japan']);
    

    有关示例的完整列表,请参阅文档:

    https://firebase.google.com/docs/firestore/query-data/queries#in_not-in_and_array-contains-any

    【讨论】:

    • 它检查一个正常的字段。不是数组。如此不同。
    【解决方案4】:
    citiesRef.where('country', 'not-in', [['USA']]);
    

    注意 [['USA']] 周围的双精度数组。您需要它来过滤掉“country”数组中包含“USA”的任何文档。

    单个数组 ['USA'] 假定 'country' 是一个字符串。

    【讨论】:

    • 如果数组只包含“美国”,它就可以工作。没用,因为数组通常包含多个值。
    • 是的,在大多数情况下它不会有用。但是,我确实使用此功能来获取不包含用户 ID 数组中的用户 ID 的文档。对我来说幸运的是,此时用户希望加入另一个用户的游戏(并且数组中只有一个用户),我不想包含当前用户可能已经开始游戏的文档寻找合作伙伴。
    猜你喜欢
    • 2020-01-08
    • 2020-12-30
    • 2021-04-07
    • 2020-07-08
    • 2020-09-25
    • 2023-03-30
    • 2020-03-26
    相关资源
    最近更新 更多