Firebase:如何为同一键查询检索两个值?

时间:2018-06-20 12:06:19

标签: android json firebase firebase-realtime-database

我要执行的操作是查询Firebase中具有相同键的两个值。 我的数据库是这样的:

"Document" : [ {
    "fileType" : "PDF",
    "language" : "en",
    "linkUrl" : "https://myfile.pdf",
    "name" : "Installation Guide"
  }, {
    "fileType" : "DOCUMENT",
    "language" : "fr",
    "linkUrl" : "https://myfile.txt",
    "name" : "text.txt"
  }

我已经在Android项目中编写了一个查询,以检索使用相同语言的所有文档,并且可以正常工作。

val selectedLanguage = LocalStorageHelper.getInstance(this)?.getSelectedLanguage()
val docRef = rootRef.child("Document").orderByChild("language").equalTo("en")

但是现在我想做的就是寻找“ en”和“ fr”。

是否可以像上面那样做,我在网上搜索过,但没有发现任何积极的结果。

4 个答案:

答案 0 :(得分:1)

您不能在Firebase数据库中使用AND子句,只能查询一种语言,因此只能执行以下操作:

orderByChild("language").equalTo("en")

答案 1 :(得分:0)

过滤客户端上的语言。

val docRef = rootRef.child("Document").orderByChild("language").on('value', function(snapshot) {
  val filteredDocuments = snapshot.val().filter(function(document) {
    return document.language === 'en' || document.language === 'fr';
  });
});

答案 2 :(得分:0)

正如@PeterHaddad在回答中提到的那样,很遗憾,Firebase中没有AND运算符。如果您说不能通过简单的操作切换到Firestore,则需要知道我们有一种解决方法可以帮助您实现同一目标。因此,要解决此问题,您可以创建一个复合节点,该节点可以容纳所有语言属性设置为enfr的对象。您的数据库结构应如下所示:

Firebase-root
  |
  --- EnFrDocuments
  |      |
  |      --- documentId
  |      |     |
  |      |     --- fileType: "PDF"
  |      |     |
  |      |     --- language: "en"
  |      |     |
  |      |     --- linkUrl: "https://myfile.pdf"
  |      |     |
  |      |     --- name : "Installation Guide"
  |      |
  |      --- documentId
  |            |
  |            --- fileType: "DOCUMENT"
  |            |
  |            --- language: "fr"
  |            |
  |            --- linkUrl: "https://myfile.txt"
  |            |
  |            --- name : "myfile.txt"
  |
  --- Documents
        |
        --- //use the same structure

我建议您将结构也用于Document节点,而不是将这些对象存储到数组中。

这种做法称为denormalization,是Firebase的常见做法。为了更好地理解,我建议您观看此视频Denormalization is normal with the Firebase Database

此外,在复制数据时,需要记住一件事。用与添加数据相同的方式,您需要对其进行维护。换句话说,如果您想更新/删除项目,则需要在它存在的每个位置进行。

答案 3 :(得分:0)

denormalization是NoSQL数据库中的一个好习惯。但是,如果做错了,则会有很多不必要的重复数据。在通常情况下,非规范化是数据的副本,但格式不同。经非规范化的数据应包含较少或其他内容,您可以从中获得针对应用程序中特定用例的某些好处。其中一些好处是下载不必要的数据较少(因为在应用程序的特定部分不需要某些数据)和不同的搜索或过滤算法。

以@Alex Mamo为例,您将为任何语言组合创建数据副本。如果您的用户可以如果选择多种语言,则您在数据库中将拥有同一个条目,且所有条目的内容都超过两次。这通常不是您想要的。 (请考虑一下en / fr,en / de,en / fr / de,也可能是en / gr等的组合。)

每当语言选择更改时,我都只会使用一个标志并用该标志更新条目。这样,您可以选择带有标志prefLang = true的文档,并在语言发生变化时更新(添加或删除标志)这些文档。 这样,唯一的数据tha就是被写入/修改的标志信息。否则,当您创建仅用于语言首选项的特殊文档时,您将复制并删除整个文档信息。

还请记住您对节点大小的限制。如@Alex所述,您应该使用多个文档节点,而不是在单个节点中使用数组。