【问题标题】:Filter data in Firebase (with complex query) android在 Firebase 中过滤数据(带有复杂查询)android
【发布时间】:2017-08-05 12:46:29
【问题描述】:

我想过滤Firebase 中的数据。我收到了一些查询,但无法按照我的要求过滤数据。

数据:

{
  "messages": {
    "Data_1": {
      "Inner_3": {
        "Text": {
          "-Kqgd2_QSi5HIlyH6Om3": {
            "date": 1501840029764,
            "text": "hi"
          },
          "-Kqgd6zZf51AdKNPrsX8": {
            "date": 1501840047829,
            "text": "hello"
          }
        }
      }
    },
    "Data_2": {
      "Inner_2": {
        "Text": {
          "-Kqm5GijxFT54wZRHIJj": {
            "date": 1.501931572192E9,
            "text": "hi"
          },
          "-Kqm5YohOG1cFWO-WNGc": {
            "date": 1.501931646257E9,
            "text": "test"
          },
          "-Kqm6935IY8Ddj20Z3TN": {
            "date": 1.501931802871E9,
            "text": "new message"
          }
        }
      }
    }
  }
}

在上面的 json 中,如果我通过 Inner_3 那么它应该返回下面的结果。如果Inner_3 可用,它会检查所有arrays,然后给我主层名称,最后一个TEXT 来自Inner_3

{
  "messages": {
    "Data_1": {
      "Text": {
        "-Kqgd6zZf51AdKNPrsX8": {
          "date": 1501840047829,
          "text": "hello"
        }
      }
    }
  }
}

请帮助我实现这个结果。

【问题讨论】:

    标签: android firebase filter firebase-realtime-database


    【解决方案1】:

    很遗憾,Firebase 数据库无法进行这种查询。您必须更改数据结构以适应它。

    一种方法是将Inner_3 添加为已知属性的值:

    {
      "messages": {
        "Data_1": {
          "Key": "Inner_3"
          "Inner_3": {
            "Text": {
              "-Kqgd2_QSi5HIlyH6Om3": { "date": 1501840029764, "text": "hi" },
              "-Kqgd6zZf51AdKNPrsX8": { "date": 1501840047829, "text": "hello" }
            }
          }
        },
        "Data_2": {
          "Key": "Inner_2"
          "Inner_2": {
            "Text": {
              "-Kqm5GijxFT54wZRHIJj": { "date": 1.501931572192E9, "text": "hi" },
              "-Kqm5YohOG1cFWO-WNGc": { "date": 1.501931646257E9, "text": "test" },
              "-Kqm6935IY8Ddj20Z3TN": { "date": 1.501931802871E9, "text": "new message" }
            }
          }
        }
      }
    }
    

    现在您可以通过以下方式查询:

    ref.child("messages").orderByChild("Key").equalTo("Inner_3")
    

    您也可以添加单独的查找列表:

    "InnerToNodeNameMapping": {
      "Inner_3": "Data_1",
      "Inner_2": "Data_2"
    }
    

    然后直接查找即可找到Inner_3项的路径:

    ref.child("InnerToNodeNameMapping").child("Inner_3")
    

    然后您可以直接访问该节点(无需查询)。

    在 Firebase 和其他 NoSQL 数据库中,必须调整/扩展您的数据结构以允许在您的应用中使用您想要的用例。由于您似乎对 NoSQL 比较陌生,我建议您阅读 NoSQL data modeling

    【讨论】:

    • 非常感谢。如果 Data_2 包含 Inner_2 和 Inner_3 怎么办?那么,我应该在 Key 中使用什么?
    • 这就变成了一个分类问题。在这里查看我更长的答案:stackoverflow.com/questions/40656589/…
    • 根据您的链接建议,我创建了不同的列表频道。
    【解决方案2】:

    您必须按键 .orderByKey() 进行排序,并获得最后一个,记住 firebase 推送的键是包含时间戳的随机字符串。

    最常用的排序方法是 ref.orderByKey()。它通过键对 ref 的孩子进行排序,通常是按键 — 按时间排序。

    按键排序快照后,您可以执行以下操作:

    var firstdata;
     snapshot.forEach(function(mySnapshot) {
      if (!firstdata) {
      firstdata = mySnapshot.val();
       }
      });
      console.log(firstdata);
    

    【讨论】:

    • .orderByKey() 很好,但主要问题是从所有上层中找到“Inner_3”。
    • 我已经在这样做了。但是,如果我有 10000 条消息,那么我认为获取所有数据并在我这边过滤它不是一个好选择。
    • 我明白,firebase 不被认为是这样做的,唯一的解决方法是循环每个元素并获取最后一个元素,或者将推送的键存储在 /times 之类的路径中,然后从最后一个键和存储文本的路径。
    猜你喜欢
    • 2018-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-09
    相关资源
    最近更新 更多