2017-08-05 52 views
0

我想筛选Firebase中的数据。我有一些疑问,但我无法按照我的要求过滤数据。

数据:在Firebase中过滤数据(使用复杂查询)android

{ 
    "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然后应该返回下面的结果。它检查所有arrays是否有Inner_3可用,然后给我主层名称和最后TEXTInner_3

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

请帮我实现这个结果。

回答

1

不幸的是那种查询是不可能的火力地堡数据库。你将不得不改变你的数据结构来适应它。

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

ref.child("messages").orderByChild("Key").equalTo("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" } 
     } 
     } 
    } 
    } 
} 

现在你可以查询

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

然后,您可以找到Inner_3项目的路径直接查询:

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

并从中可以直接访问节点(无需查询)。

必须调整/扩展您的数据结构以允许您的应用中需要的用例在Firebase和其他NoSQL数据库中非常常见。由于您对NoSQL看起来相对较新,所以我推荐阅读NoSQL data modeling

+0

非常感谢。如果Data_2包含Inner_2和Inner_3两者,该怎么办?那么,我应该在Key中使用什么? –

+0

这变成了一个分类问题。在这里看到我更长的答案:http://stackoverflow.com/questions/40656589/firebase-query-if-child-of-child-contains-a-value –

+0

根据您的链接建议,我创建了不同的频道列表。 –

0

您必须按键.orderByKey()进行排序,并获得lastone,rember firebase推送的密钥是包含时间戳的随机字符串。

最常见的排序方法是ref.orderByKey()。它通过按键命令裁判的孩子,通常按下按键 - 按时间排序。

你有你的快照通过键排序后,你可以做这样的事情:

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

'.orderByKey()'很好,但主要问题是从所有上层找到'Inner_3'。 –

+1

我已经在做这个。但是如果我有10000条消息,那么我认为获取所有数据并过滤它是不好的选择。 –

+0

据我所知,firebase没有被认为这样做,唯一的解决方法是循环每个元素并获得最后一个,或将按键存储在像/ times这样的路径中,然后从那里检索最后一个键和路径它存储文本的位置。 –