【问题标题】:Firebase - how to perform a where item in list query?Firebase - 如何在列表查询中执行 where 项?
【发布时间】:2016-03-27 18:28:23
【问题描述】:

给定

url根是:https://myApp.firebaseio.com

还有

数据是:

  {
    "users": {
      "u00001": {
        "name": "Andy",
        "teams": {
           "t001": true,
           "t003": true
        }
      },
      ...
    },
    "teams": {
      "t001": {
        "name": "Alpha Team"
      },
      "t002": {
        "name": "Beta Team"
      },
      "t003": {
        "name": "Gamma Team"
      },
      ...
    }
  }

Andy 加入的团队是 ['t001', 't003']

问题:

是否可以使用 ONE 查询来获取 Andy 加入的所有团队的名称? (查找所有团队名称,其中 ID 在 ['t001', 't003'] 中,例如期望 ["Alpha Team", "Gamma Team"])

提前致谢。

【问题讨论】:

  • 你写过代码吗?你有什么问题?
  • 请告知我需要做什么来证明我已经尝试过。我不得不承认我不擅长弹性搜索,如果它可以轻松解决我的问题。目前我需要一个带有 2 个团队 ID 的循环来执行 2 次提取。例如new Firebase("myApp.firebaseio.com/teams" + teamId).on("value", function(data){ ... }).
  • 我不怀疑您已经为此工作了一段时间,但您的问题并没有反映出这种努力。您至少应该能够使用Firebase documentation on queries 中的信息构建查询。您无法让您的查询正常工作,我们可以提供帮助。

标签: javascript firebase firebase-realtime-database


【解决方案1】:

这应该可行:

var ref = new Firebase('https://myApp.firebaseio.com');
ref.child('users/u00001/teams').on('value', function(teamKeys) {
  var teamNames = [];
  teamKeys.forEach(function(teamKey) {
    ref.child('teams').child(teamKey.key()).once('value', function(teamSnapshot) {
      teamNames.push(teamSnapshot.val().name);
      if (teamNames.length == teamKeys.numChildren()) {
        console.log('All team names loaded');
      }
    }); 
  });
})

如果您担心加载时间和往返次数,请参阅Speed up fetching posts for my social network app by using query instead of observing a single event repeatedly

【讨论】:

  • 感谢 if 语句:if (teamNames.length == teamKeys.numChildren()) { ... }。我可以解决其中的承诺。
  • 是的。但我希望你也意识到,如果这是你要问的唯一部分,那么这段代码的其余部分应该在你的问题中。
  • 这是我从您的回答中得到的额外好处,谢谢。我在 ONE 查询之后得到结果,而不依赖于客户端的循环承诺。而我仍然没有找到答案。 (我知道如何使用 startAt(text).endAt(text) 进行过滤,但我找不到适合列表内过滤的解决方案)
  • 以最小的单次读取获取数据的唯一方法是将您想要的信息存储在一个位置。没有其他神奇的方法。但是上述方法已经足够快了。如果您仍然不这么认为,请再次阅读链接的答案......一次又一次......一次又一次。相反,如果您在将其转换为 Promise 时遇到问题,请发布 尝试过的内容。
  • 感谢您指出除了重组我的数据之外别无他法。 (我也不想将团队名称放在用户名下,所以我必须先获取团队 ID,然后再查找团队)。我知道这一切都是异步发生的,因此请求不会排队。我设法提取了数据,但只是觉得必须有更好的方法(由于我不熟悉 NoSQL 数据库查询)。另外,我认为这是许多 Firebase 爱好者心中的真实问题,所以请注意,我提出这个问题的目的是为了支持 Firebase 社区。​​span>
【解决方案2】:

var data = { "users": { "u00001": { "name": "Andy", "teams": { "t001": true, "t003": true } }, }, "teams": { "t001": { "name": "Alpha Team" }, "t002": { "name": "Beta Team" }, "t003": { "name": "Gamma Team" } } }

function getNames(data, user) {
    var res = [];
    var teams = [];
    Object.keys(data.users).forEach(k => {
        if (data.users[k].name == user) {
            Object.keys(data.users[k].teams).forEach(t => teams.push(t))
        }
    });
    Object.keys(data.teams).forEach(t => {
        if (teams.indexOf(t) > -1) {
            res.push(data.teams[t].name);
        }
    });
    return res;
}

document.write(JSON.stringify(getNames(data, "Andy")));

【讨论】:

  • 这绝对适用于 JSON。在这种情况下,问题也与云托管 JSON 的 Firebase 有关。虽然您可以下载整个 JSON 并使用您的代码在客户端进行过滤,但随着数据大小的增长,这将变得笨拙。使用 Firebase 查询可确保在服务器上进行过滤(如果定义了正确的索引),因此不会出现潜在的性能问题。
  • 顺便说一句:很高兴看到一个可运行的 sn-p。这是我在回答 Firebase 问题时错过的一件事,因为在 sn-ps 中无法访问数据库。 :-/
  • @FrankvanPuffelen Firebase 不错,但我对它还不是很熟悉,谢谢指点我:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-20
  • 2019-10-30
  • 2012-09-27
  • 2021-12-14
  • 1970-01-01
  • 2021-11-17
  • 1970-01-01
相关资源
最近更新 更多