如何在 Angularfire 中按动态对象属性进行过滤
How to filter by dynamic object properties in Angularfire
我在 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 中似乎有所不同。
我知道如果我将它更改为用户 ID 数组,我可以通过 array-contains
查询,我的问题是为什么这不起作用以及如何使其起作用。
您的屏幕截图中的 playerIds
字段不是一个数组,而是一个包含键 bTr2...
和 lnm4...
且值为 true
的映射。不幸的是,您需要为该地图中的每个字段创建一个单独的索引。
为了能够使用单个索引,将 playerIds
字段转换为实际数组:
playerIds: ["bTr2...", "lnm4..."]
有了这个结构,你:
- 只需要一个索引,在
playerIds
字段上。
- 可以用
array-contains
查询。
- 可以使用
arrayUnion
向数组添加项目。
- 使用
arrayRemove
从数组中删除项目。
另请参阅 updating elements in an array 上的文档。
尽管 Frank van Puffelen 的解决方案有效,但我发现了问题所在。
似乎如果我们有多个 where
或 order
需要索引,问题是不可避免的。在我的例子中,我发现我应该在第二个 where
中使用 ==
而不是 !=
,当我更改它时,它不需要任何索引并且我能够像那样查询
ref.where(`playerIds.${user.id}`, '==', true).where(`status`, '==', GameStatus.Started)
我在 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 中似乎有所不同。
我知道如果我将它更改为用户 ID 数组,我可以通过 array-contains
查询,我的问题是为什么这不起作用以及如何使其起作用。
您的屏幕截图中的 playerIds
字段不是一个数组,而是一个包含键 bTr2...
和 lnm4...
且值为 true
的映射。不幸的是,您需要为该地图中的每个字段创建一个单独的索引。
为了能够使用单个索引,将 playerIds
字段转换为实际数组:
playerIds: ["bTr2...", "lnm4..."]
有了这个结构,你:
- 只需要一个索引,在
playerIds
字段上。 - 可以用
array-contains
查询。 - 可以使用
arrayUnion
向数组添加项目。 - 使用
arrayRemove
从数组中删除项目。
另请参阅 updating elements in an array 上的文档。
尽管 Frank van Puffelen 的解决方案有效,但我发现了问题所在。
似乎如果我们有多个 where
或 order
需要索引,问题是不可避免的。在我的例子中,我发现我应该在第二个 where
中使用 ==
而不是 !=
,当我更改它时,它不需要任何索引并且我能够像那样查询
ref.where(`playerIds.${user.id}`, '==', true).where(`status`, '==', GameStatus.Started)