【问题标题】:How to filter by dynamic object properties in Angularfire如何在 Angularfire 中按动态对象属性进行过滤
【发布时间】:2021-03-06 17:24:34
【问题描述】:

我在 Angular + AngularFire + Firestore 项目中有如下模型

export interface Game {
    id: string;
    ... some other properties
    players: Array<{
       userId: string;
       name: string;
       picture: string;
    }>;
    playerIds: { [userId: string]: boolean };
}

数据看起来像这样

现在我想查询特定 userId 是玩家之一的所有记录。

因为我只想过滤userId(不是整个玩家对象),我不能使用array-contain,所以我添加了一个playerIds属性,它是一个地图对象。

我的代码是这样的


    this.collection((ref) => ref.where(`playerIds.${user.id}`, '==', true).where(`status`, '!=', GameStatus.Started)).valueChanges(),

然后它要求我为这个查询创建一个索引。问题是索引对于该用户来说非常具体,并且包含该特定用户 ID。

在我在 nodejs 中使用 firebase 的另一个项目中,我一遍又一遍地做同样的事情,但在 AngularFire 中似乎有所不同。

我知道如果我将其更改为可以通过array-contains 查询的 userId 数组,我的问题是为什么这不起作用以及如何使它起作用。

【问题讨论】:

    标签: angular firebase google-cloud-firestore angularfire


    【解决方案1】:

    您在屏幕截图中的playerIds 字段不是一个数组,而是一个映射,其键为bTr2...lnm4...,值为true。不幸的是,您需要为该地图中的每个字段创建一个单独的索引。

    为了能够使用单个索引,请将playerIds 字段转换为实际数组:

    playerIds: ["bTr2...", "lnm4..."]
    

    有了这个结构,你:

    • 只需要一个索引,在 playerIds 字段上。
    • 可以通过array-contains查询。
    • 可以使用arrayUnion向数组中添加项目。
    • 使用arrayRemove 从数组中删除项目。

    另请参阅updating elements in an array 上的文档。

    【讨论】:

    • 感谢您的回答,虽然您的解决方案会起作用,但我刚刚找出问题的根本原因并开始工作,问题是!= 过滤器的组合状态,当我意外删除时那,它开始工作了。所以我将该状态过滤器移至 rxjs 地图
    • 很高兴听到你想通了@Reza。 ?。可能值得将其(带有代码)发布为自我答案,因此其他人将来更有可能看到它。
    • 我标记了你的答案和正确的解决方案,因为如果需要索引似乎没有办法
    【解决方案2】:

    虽然 Frank van Puffelen 的解决方案有效,但我发现出了什么问题。

    如果我们有多个需要索引的whereorder,问题是不可避免的。就我而言,我发现我应该在第二个where 中使用== 而不是!=,当我更改它时,它不需要任何索引,我可以这样查询

    ref.where(`playerIds.${user.id}`, '==', true).where(`status`, '==', GameStatus.Started)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-31
      • 2013-07-21
      • 2016-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-23
      相关资源
      最近更新 更多