gpt4 book ai didi

javascript - Firebase 查询子级的子级是否包含值

转载 作者:行者123 更新时间:2023-11-30 11:25:15 25 4
gpt4 key购买 nike

表的结构是:

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

等等

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

这是我到目前为止所拥有的:

 subscribeChats(username: string) {
return this.af.database.list('chats', {
query: {
orderByChild: 'participants',
equalTo: username, // How to check if participants contain username
}
});
}

最佳答案

您当前的数据结构非常适合查找特定聊天的参与者。然而,这并不是一个很好的查找逆向结构:用户参与的聊天。

这里有一些问题:

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

设置与数组

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

participants: ["puf", "puf"]

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

我的经验法则:如果您发现自己在编写array.contains(),那么您应该使用集合

集合是一种结构,其中每个子项最多只能出现一次,因此它自然可以防止重复。在 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"]
}
}
}
}
}

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

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

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

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

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

现在您可以通过以下方式简单地确定您的聊天室列表:

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

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

您希望应用中有两个相关列表:

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

在这种情况下,数据库中也会有这两个列表。

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 的倒排索引。

云 Firestore

这是 Cloud Firestore 对此类查询提供更好支持的情况之一。它的 array-contains 运算符允许过滤数组中具有特定值的文档,而 arrayRemove 允许您将数组视为一个集合。有关这方面的更多信息,请参阅 Better Arrays in Cloud Firestore .

关于javascript - Firebase 查询子级的子级是否包含值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50805782/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com