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

2023-11-26

表的结构是:

  • chats
  • --> 随机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
        }
    });
 }

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

这里有几个问题:

  • 你正在存储一个set作为数组
  • 您只能在固定路径上建立索引

集合与数组

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

participants: ["puf", "puf"]

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

我的经验法则:如果你发现自己在写作array.contains(),你应该使用一组.

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

participants: {
  "puf": true
}

The true这实际上只是一个虚拟值:重要的是我们已将名称移至键。现在,如果我尝试再次加入此聊天,那就毫无意义了:

participants: {
  "puf": true
}

当你加入时:

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

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

您只能索引已知属性

有了上面的结构,你could查询您正在进行的聊天:

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.

云Firestore

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Firebase 查询子级的子级是否包含值 的相关文章

随机推荐

  • 如何在 SELECT 语句中使用 BOOLEAN 类型

    我有一个参数为 BOOLEAN 的 PL SQL 函数 function get something name in varchar2 ignore notfound in boolean 此功能是第三方工具的一部分 我无法更改它 我想在
  • 如何授予 ASP.NET 写入 Windows 7 文件夹的权限?

    我有一个新的 Win7 工作站 我正在尝试让 ScrewTurn Wiki 在该机器上运行 我的 STW 安装使用文件系统选项来存储其数据 因此我需要向网站安装文件夹中的 ASP NET 工作进程授予写入权限 然而 我似乎无法想出 Win7
  • 如何更改 openshift 容器平台中的权限?

    我是 Openshift 的新手 我已经在 openshift 中部署了一个应用程序 当我检查日志时 某些文件存在权限被拒绝错误 现在 我想更改已部署在 Openshift 中的容器的权限 但收到 不允许操作 警告 我该如何解决 这是针对运
  • 面试:为集合的集合设计一个迭代器

    在java中为集合的集合设计一个迭代器 迭代器应该隐藏嵌套 允许您迭代属于所有集合的所有元素 就像使用单个集合一样 这是一个老问题 但现在 2019 年 我们有了 JDK8 的好东西 特别是 我们有流 这使得这项任务变得简单 public
  • 自定义 Mathematica 快捷键

    Is there a place I can view change global shortcut options like Command 9 turn into Input style 特别是 我需要一种更快的方法来创建项目符号列表
  • 从元组列表中格式化 JSON 字符串的更 Pythonic 方式

    目前我正在这样做 def getJSONString lst join rs for i in lst rs join str i 0 str i 1 join return rs 我称之为 rs getJSONString name va
  • 字符串中的 JSON 转义序列无效

    我正在使用一个 MySQL 数据库 它为谷歌地图编码了多边形 当我尝试以 json 形式返回查询时 jsonlint 抱怨 我不确定为什么它抱怨 我确实尝试转义 latlon 中的 但仍然得到相同的错误 Parse error on lin
  • JavaScript:打印前 12 个月——“March”打印两次?

    我正在尝试编写一个脚本来打印过去 12 个月的名称 由于本月是一月 因此应该打印 十二月 十一月 十月 九月 八月 七月 六月 可能 四月 行进 二月 一月 相反 它打印 March 两次 http jsfiddle net h69gm04
  • 有什么方法可以分析 firestore 数据库吗?

    我的 Firestore 数据库中的实体写入数量非常多 大多数路径的写入权限都受到限制 通过后端服务器使用 admin SDK 完成 只有极少数路径具有写访问权限 特别是仅对已通过身份验证 注册 加入和批准的特定组的用户而言 因此即使滥用的
  • 连接到 Amazon RDS Oracle 实例时如何解决“读取调用减一”错误

    我在 Amazon RDS 实例上运行 Oracle 11GR2 有时我会得到一个IO Error Got minus one from a read call当打电话给DriverManager getConnection getUrl
  • Git 哈希重复

    Git 允许使用以下命令检索提交的哈希值 git rev parse HEAD 这使33b316c or git rev parse short HEAD 这使33b316cbeeab3d69e79b9fb659414af4e7829a32
  • 错误:未找到名称“ngModel”的导出

    构建我的角度项目后 我收到错误 错误 未找到名称 ngModel 的导出 我的 UI 在 Docker 容器中运行 甚至不知道在哪里寻找这个 它在开发中工作正常 发球 有任何想法吗 我有同样的错误 尽管在开发中 事实证明我没有添加表单模块模
  • 如何从 Google Analytics 获取原始日志?

    是否可以从 Google Analytic 获取原始日志 有没有可以从GA生成原始日志的工具 不 您无法获取原始日志 但没有什么可以阻止您将完全相同的数据记录到您自己的 Web 服务器日志中 看看顽童代码并借用它 将以下两行更改为指向您的
  • 如何创建 AND 或 OR 表达式?

    我写了这个 if a 11 b 1 if a 1 AND b 1 但两者都不起作用 我也有同样的问题OR 如何编写包含以下内容的表达式OR or AND You use 对于 和 以及 为 或
  • 如何将 JavaScript onClick 处理程序添加到嵌入的 html 对象?

    我正在尝试将 onClick 处理程序添加到嵌入对象中 处理程序需要执行外部 js 文件中的函数 该文件通过链接到当前 html 文件button svg id buttonEmbed width 95 height 53 type ima
  • keras LSTM 层训练时间太长

    每当我在 Keras 上尝试 LSTM 模型时 似乎由于训练时间过长 该模型无法训练 例如 像这样的模型每步需要 80 秒来训练 def create model self inputs inputs input lstm placehol
  • 基于 TCP 的 WebRTC 媒体?

    我是 WebRTC 新手 我了解了回合服务器 下面的内容用于为 webrtc 应用程序配置基于 TCP 的 Turn 服务器 webrtc 应用程序中的转向服务器配置示例 url turn 192 158 29 39 3478 transp
  • 从十六进制值检测相似的颜色

    有谁知道一种获取两个十六进制颜色值并返回某种索引来说明颜色有多相似的方法 例如 两种黄色色调可能会返回更高的指数 即它们比灰色和黄色更相似 我正在使用 javascript 但我猜这样的东西将是一个独立于语言的公式 算法 可以从以下算法开始
  • 如何在 Mono For Android 中将位图转换为字节数组

    我正在使用 Mono for Android 我想将位图保存到字节数组 所以我可以将它保存到数据库中 在这里搜索我发现了以下代码 ByteArrayOutputStream bos new ByteArrayOutputStream bit
  • Firebase 查询子级的子级是否包含值

    表的结构是 chats gt 随机ID gt gt 参与者 gt gt gt 0 名称1 gt gt gt 1 名称2 gt gt 聊天项目 etc 我想做的是查询聊天表 以查找通过传入的用户名字符串容纳参与者的所有聊天 这是我到目前为止所