【问题标题】:Firebase: How to get document in sub collection without the parent keyFirebase:如何在没有父键的情况下获取子集合中的文档
【发布时间】:2021-12-10 05:57:14
【问题描述】:

我需要执行查询以获取子集合中最旧的文档。 我想用尽可能少的读取来执行这个查询。 数据库说明: 基于 Firebase。 设备的集合。每个设备都包含一组回调。对于特定设备,我需要获取最早的回调(回调有时间戳)。

我想我知道如何使用设备唯一 ID 执行此查询,但我想通过设备的某些字段过滤来做到这一点,此字段也是唯一的。 我可以通过使用他的所有回拨来查询设备来做到这一点,但这会向我收取实际需要的更多读取费用。

使用 ID 工作的查询:

  admin
    .firestore()
    .collection("devices/{device_id}/callbacks")
    .{order_by_timestamp}
    .limit(1)
    .get()
    .then((data) => {
      let callbacks = [];
      data.forEach((doc) => {
        callbacks.push(doc.data());
      });

      return res.json(callbacks);
    })
    .catch((err) => console.error(err));

【问题讨论】:

    标签: node.js firebase google-cloud-firestore collections


    【解决方案1】:

    如果设备集合中的该字段是唯一的,则您可以先获取该设备的 ID,然后继续执行现有逻辑,如下所示:

    async function getOldestCallback(thatFieldValue) {
      const device = await admin.firestore().collection("devices").where("thatField", "==", thatFieldValue).get()
    
      if (device.empty) return false;
      
      const deviceId = device[0]["id"];
    
      // existing function
    }
    

    这将导致 2 次读取(1 次用于设备文档,1 次用于最旧的回调(如果存在)。

    此外,由于您将要返回的文档数限制为 1,因此您可以使用 [0] 而不是使用 forEach 循环。

    const callbacks = [ data[0].data() ]
    

    【讨论】:

    • 好的。那么在事先不知道设备id的情况下,有没有办法在一次读取操作中执行这个查询呢?谢谢你的提示!
    • @Ofir 一种方法是将该字段也存储在回调文档中,然后使用集合组查询..admin.firestore().collectionGroup("callbacks").where(....)。只需为多个字段链接多个where()
    • 好主意。我的另一个想法是使用设备唯一字段作为设备 ID(从技术上讲,它不会引起问题)。问题是客户知道这个领域。如果客户知道,我不确定将其用作 ID 是否是个好主意。
    • @Ofir 我不完全确定它的用例,但如果客户已经知道它,那么问题是什么?您可以使用安全规则,以便只有允许的用户才能在需要时访问数据。
    • 也许正确的方法就像你说的那样。使用唯一字段作为 ID 而不是 Firebase 随机 ID,并使用安全规则来限制访问。
    猜你喜欢
    • 1970-01-01
    • 2022-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-24
    • 2019-10-06
    • 2020-10-23
    • 2021-01-23
    相关资源
    最近更新 更多