当前位置: 首页 > 面试题库 >

Cloud Firestore-如何从两个集合中获取关系数据?

洪开济
2023-03-14
问题内容

我想在Cloud Firestore中定义这两个集合。一些示例数据如下所示:

播放清单:

  • 名称:“ playlist1”
  • songCount://要实时计算

歌曲:

  • 标题:“ song1”
  • playlistId:“ playlist1”

  • 标题:“ song2”

  • playlistId:“ playlist1”

  • 标题:“ song3”

  • playlistId:“ playlist1”

此外,在我的Android应用中,我想显示所有播放列表和所有歌曲的单独列表。但是,在显示所有播放列表的列表时,我想根据“
songCount”中的值显示每个播放列表的名称以及每个播放列表中包含的歌曲数。

请告知我需要在Cloud
Firestore中进行哪种查询以实现此目标。是否有JOIN可用的函数,或者我是否必须将Songs集合放入循环并将具有playlistId的歌曲计数为“
playlist1”,然后对要在播放列表列表中显示的所有播放列表重复该功能?我想拥有一个更智能的解决方案,但在互联网上找不到。

任何帮助都是很大的帮助。谢谢你的时间。


问题答案:

是否有加入功能?

不幸的是,JOINFirestore中没有查询。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对象即可。

关于与播放列表相对应的所有歌曲的计数,建议您从本
帖子中
看到我的答案,在此我已经解释了可以实现的目标。因此,根据我回答的最后一部分,您的Firebase实时数据库结构应如下所示:

Firebase-Realtime-Database-root
    |
    --- playlists
          |
          --- playListIdOne: numberOfSongs
          |
          --- playListIdTwo: numberOfSongs

编辑:

我不能说我已经完全理解它,尤其是因为第一个答案涉及Firestore,第二个答案涉及Firebase Realtime Database。

我给您提供此解决方案是因为,如果您希望每次添加或删除歌曲时都使用Cloud
Firestore计数和更新元素,则Firestore将对每次写入/删除操作收取费用。Firebase实时数据库还有另一个定价计划,因此您无需为此付费。请参阅Firestore定价请重新阅读直到最后,这是我对本
帖子的 回答。

另外,我真的无法获得计算歌曲数的过程。

这样可以从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中,这种做法被称为并且是一种常见的做法。为了更好地理解,我建议您观看此视频,使用Firebase数据库可以正常进行非规范化。它适用于Firebase实时数据库,但相同的规则适用于Cloud
Firestore。

此外,在复制数据时,需要记住一件事。用与添加数据相同的方式,您需要对其进行维护。换句话说,如果您要更新/删除项目,则需要在项目存在的每个位置进行。

请记住,同一首歌曲可以在多个播放列表中找到。

没关系,因为每首歌都有不同的ID。



 类似资料:
  • 几个月前我已经开始使用spring和mongodb。到目前为止,我还不知道如何使用Mongotemplate或MongoRepository从多个集合中提取数据。我有两个集合的人和联系人。现在我想获取客户列表和联系人。Customer的id是IS_ID,而Contact的关系id是customerId,所以我如何获得数据的Customer联系人详细信息。

  • 我使用的是Vue.js和Firebase FiRecovery。现在我有两个集合和。在订单集合中,我已经存储了集合的每个文档的id。我现在必须从中获取相应用户的详细信息。我应该怎么做?这是我迄今为止所做的 我需要在userInfo中存储用户数据。提前谢谢

  • 问题内容: 我有一个具有单向一对多关系的类,如下所示: 通常,获取此订单的内容很简单: 但是无论出于何种原因,我都可能希望以某种方式过滤结果并仅以最快的方式检索部分商品集合,例如高于一定价格,低于一定库存的所有商品(不返回然后全部过滤)然后)。为此,我将运行HQL查询以检索特定订单的商品,并将更多内容添加到我的where子句或查询对象中。 凭直觉我会想要这种行为(这是完全错误的): 但是当然这是错

  • 我的Go应用程序上有这两个结构 我在前端使用Angular,所以如果我不需要提出两个请求来获得客户然后是地址,这将是非常实用的。 我在这里搜索了,但没有找到一对一关系的示例,有没有办法让这个查询不仅获得客户数据,而且还获得地址?

  • 当数据存储在多个集合中时,如何显示配置文件的详细数据 尝试了此链接 预期的结果将来自数据应该获取的所有集合,但使用我的代码,它给出的结果直到specialty,但在此之后,它只打印ObjectID

  • 我想从最终结果中删除一些属性,并在这里找到了这个从Laravel集合中仅获取特定属性 这适用于顶层,但需要从相关项目中删除一些属性,例如用户有一个访问卡,并且访问卡的属性中有一些长文本详细信息。 我想从最终结果中删除该属性。使用链接中提到的方法是否可行?