有加入功能吗?
很遗憾,Firestore 中没有 JOIN 查询。 Firestore 中的查询很浅:它们仅从运行查询的集合中获取项目。无法在单个查询中从顶级集合和其他集合或子集合中获取文档。 Firestore 不支持一次性跨不同集合进行查询。单个查询只能使用单个集合中文档的属性。所以我能想到的最简单的解决方案是使用类似这样的数据库结构:
Firestore-root
|
--- playlists (collection)
| |
| --- playListId (document) //The unique id of the play list
| |
| --- name: "playlist1"
|
--- songs (collection)
|
--- playListId (document) //The same as the above playListId
|
--- playListSongs
|
--- songId
|
--- title: "song1"
为了显示所有播放列表,只需将侦听器附加到 playlists 引用并获取所有 playlist 对象。如果您想获取与特定播放列表对应的所有歌曲,只需将侦听器附加到 songs\playListId\playListSongs 并获取所有 song 对象。
关于与播放列表对应的所有歌曲的数量,我建议您查看我在此 post 中的回答,我已在其中解释了您可以实现这一目标的方法。所以根据我回答的最后一部分,你的 Firebase 实时数据库结构应该是这样的:
Firebase-Realtime-Database-root
|
--- playlists
|
--- playListIdOne: numberOfSongs
|
--- playListIdTwo: numberOfSongs
编辑:
我不能说我完全理解它,尤其是因为第一个答案涉及 Firestore,第二个涉及 Firebase 实时数据库。
我为您提供了这个解决方案,因为如果您想在每次添加或删除歌曲时使用 Cloud Firestore 来计算和更新元素,Firestore 将针对每次写入/删除操作向您收费。 Firebase 实时数据库还有另一个 pricing plan,因此您无需为此付费。见Firestore pricing 请再读一遍直到最后,我的回答来自这个post。
另外,我无法真正了解计算歌曲数量的程序。
这是您从 Firestore 获取歌曲数量并将其写入 Firebase 实时数据库的方法:
rootRef.collection("songs").document(playListId).collection("playListSongs")
.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
Log.d("TAG", task.getResult().size() + "");
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference playListIdRef = rootRef.child("playlists").child(playListId);
playListIdRef.setValue(task.getResult().size());
} else {
Log.d(TAG, "Error getting documents: ", task.getException());
}
}
});
你可以这样阅读:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference playListIdRef = rootRef.child("playlists").child(playListId);
ValueEventListener valueEventListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
long playListIdOne = dataSnapshot.getValue(String.Long);
Log.d(TAG, "playListIdOne: " + playListIdOne);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage());
}
};
playListIdRef.addListenerForSingleValueEvent(valueEventListener);
其次,根据您建议的结构,我如何获得所有播放列表中所有歌曲的列表?
在这种情况下,您应该创建另一个集合,名为 allSongs。数据库中的附加集合应如下所示:
Firestore-root
|
--- allSongs
|
--- songId
|
--- //song details
这种做法称为denormalization,是 Firebase 的常见做法。为了更好地理解,我建议您观看此视频,Denormalization is normal with the Firebase Database。它适用于 Firebase 实时数据库,但同样的规则适用于 Cloud Firestore。
此外,当您复制数据时,您需要记住一件事。与添加数据的方式相同,您需要对其进行维护。换句话说,如果你想更新/删除一个项目,你需要在它存在的每个地方都这样做。
请记住,同一首歌曲可以在多个播放列表中找到。
没关系,因为每首歌都有不同的id。