8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

Firebase 查询 child 的 child 是否包含值

NMR 2月前

52 0

该表的结构是:聊天--> randomId-->--> 参与者-->-->--> 0:'name1'-->-->--> 1:'name2'-->--> chatItems 等我想做的是查询聊天表以查找所有

该表的结构如下:

  • 聊天
  • --> 随机ID
  • -->--> 参与者
  • -->-->--> 0: '名称1'
  • -->-->--> 1:'名称2'
  • -->--> 聊天物品

ETC

我想要做的是查询聊天表以通过传入的用户名字符串查找包含参与者的所有聊天。

以下是我目前所掌握的信息:

 subscribeChats(username: string) {
    return this.af.database.list('chats', {
        query: {
            orderByChild: 'participants',
            equalTo: username, // How to check if participants contain username
        }
    });
 }
帖子版权声明 1、本帖标题:Firebase 查询 child 的 child 是否包含值
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由NMR在本站《firebase》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 很好的解释。这是一个绝佳的例子,说明如何以不同的方式对数据进行建模,以充分利用 NoSQL(以及使用它的廉价平台)。

  • GMB 2月前 0 只看Ta
    引用 3

    @frank-van-puffelen 引用您最后的代码片段,假设我是 \'user1\',我获取了我所属聊天室的所有密钥。然后,对于每个聊天室密钥,我获取完整的聊天室对象,并在列表中显示聊天室列表。这很好,但是,如果我还需要访问聊天室中的完整用户对象怎么办。这似乎很奇怪,我必须对每个聊天室中的每个用户执行另一个 for 循环(2 级嵌套 for 循环!)获取数据。有没有更好的方法?

  • 这是一个很棒的解释。我的数据是这样存储的,这样我就可以从用户列表中抓取聊天室,或者从聊天室的成员中抓取用户。但它不允许观察我所属聊天室的 .childChanged。如果我尝试为成员/myId = true 的聊天设置观察者,那么我会收到未指定的索引错误。你会怎么做?我在这里发布了一个问题:.com/questions/47769044/…

  • 您当前的数据结构非常适合查找特定聊天的参与者。但是,它不是一个很好的结构,无法查找相反的内容:用户参与的聊天。

    这里有几个问题:

    • 你将集合存储数组
    • 您只能在固定路径上建立索引

    集合与数组

    一个聊天可以有多个参与者,因此你将其建模为一个数组。但这实际上不是理想的数据结构。每个参与者可能只能参与一次聊天。但通过使用数组,我可以:

    participants: ["puf", "puf"]
    

    这显然不是您想要的,但数据结构允许这样做。您可以尝试在代码和安全规则中确保这一点,但如果您从隐式匹配模型的数据结构开始,会更容易。

    我的经验法则: if you find yourself writing array.contains() , you should be using a set .

    集合是一种结构,其中每个子元素最多只能出现一次,因此它自然可以防止出现重复。在 Firebase 中,你可以将集合建模为:

    participants: {
      "puf": true
    }
    

    这里 true 实际上只是一个虚拟值:重要的是我们已将名称移至键。现在,如果我再次尝试加入此聊天,则会出现错误:

    participants: {
      "puf": true
    }
    

    当你加入时:

    participants: {
      "john": true,
      "puf": true
    }
    

    这是您的要求最直接的表述:一个只能包含每个参与者一次的集合。

    只能索引已知属性

    通过上述结构,您 可以 查询您正在参与的聊天:

    ref.child("chats").orderByChild("participants/john").equalTo(true)
    

    问题在于,这需要您在“participants/john\”上定义一个索引:

    {
      "rules": {
        "chats": {
          "$chatid": {
            "participants": {
              ".indexOn": ["john", "puf"]
            }
          }
        }
      }
    }
    

    这会起作用并且性能很好。但现在每次有新人加入聊天应用程序时,您都需要添加另一个索引。这显然不是一个可扩展的模型。我们需要更改数据结构以允许您想要的查询。

    反转索引 - 向上拉类别,使树变平

    第二条经验法则: 对数据进行建模以反映您在应用中显示的内容 .

    由于您希望显示用户的聊天室列表,因此请存储每个用户的聊天室:

    userChatrooms: {
      john: {
        chatRoom1: true,
        chatRoom2: true
      },
      puf: {
        chatRoom1: true,
        chatRoom3: true
      }
    }
    

    现在,您可以轻松使用以下方法确定您的聊天室列表:

    ref.child("userChatrooms").child("john")
    

    然后循环遍历钥匙以获取每个房间。

    您将希望在您的应用中拥有两个相关列表:

    • 特定用户的聊天室列表
    • 特定聊天室的参与者列表

    在这种情况下,您还将在数据库中拥有这两个列表。

    chatroomUsers
      chatroom1
        user1: true
        user2: true
      chatroom2
        user1: true
        user3: true
    userChatrooms
      user1:
        chatroom1: true
        chatroom2: true
      user2:
        chatroom1: true
      user2:
        chatroom2: true
    

    我已将两个列表拉到树的顶层,因为 Firebase 建议不要嵌套数据。

    在 NoSQL 解决方案中,同时拥有这两个列表是完全正常的。在上面的例子中,我们将以下列表称为 userChatrooms 倒排索引: chatroomsUsers .

    Cloud Firestore

    这是 Cloud Firestore 对此类查询提供更好支持的案例之一。其 array-contains 运算符允许过滤数组中具有特定值的文档,同时 arrayRemove 允许您将数组视为集合。有关更多信息,请参阅 Cloud Firestore 中的更好的数组 .

返回
作者最近主题: