2015-12-22 38 views
2

這是數據看起來的樣子:Firebase:如何查詢來自兩個節點的非重疊數據?

數據結構

"uid0" : { 
     "name": "adam" 
}, 
"uid1" : { 
     "name": "jonh", 
     "likes" : { 
      "uid2" : true 
     } 
}, 
"uid2" : { 
     "name": "jane", 
     "likes" : { 
      "uid0" : true, 
      "uid1" : true 
     } 
}, 
"uid3" : { 
     "name": "mark" 
} 

如何找到誰沒有被喜歡所有UID2用戶? (即結果應該是UID3,在上述情況下)

codepen:http://codepen.io/rattanakchea/pen/gPwpQq?editors=101

火力:https://datastructure.firebaseio.com/users.json

+0

你可以編輯你的文章,並複製/粘貼實際(編輯)的數據結構,而不是圖形? – Jay

+0

啊 - 更清晰的問題。看到我真正囉嗦的最新答案。 – Jay

回答

2

也許一個稍微不同的結構將提供更多的靈活性

 users 
     -Ji94-0df-k00ksdf 
     name: "john" 
     liked: true 
     -kKoakoksdookasdp 
     name: "jane" 
     liked: true 
     -Lkaamsioadoisjg 
     name: "james" 
     liked: false 

查詢的用戶節點where liked = false

您可以通過添加say .. number_of_likes以及

 users 
       -Ji94-0df-k00ksdf 
       name: "john" 
       number_of_likes: 1,000,000 
       -Lkaamsioadoisjg 
       name: "james" 
       number_of_likes: 0 

的,你可以在

之間

編輯查詢是不喜歡任何人(0)或最喜歡的(1M)或任何東西:更新基於更新和添加其他答案(S)信息

有幾個簡單的解決方案:

之一是每個用戶中跟蹤喜好和no_status。採用這種結構是微不足道找到uid_2有沒有喜歡或不喜歡

user 
    uid_0 
    likes 
    uid_1 
    uid_2 
    no_status 
    uid_3 
    uid_1 
    likes 
    uid_0 
    uid_2 
    no_status 
    uid_3 
    uid_2 
    likes 
    uid_0 
    uid_1 
    no_status 
    uid_3 

沿着相同的路線另一個選擇是轉儲布爾和一個三態去(或但是需要許多州)

哪些用戶
user 
    uid_0 
    likable_status 
    uid_1: "yes" 
    uid_2: "no" 
    uid_3: "unknown" 
    uid_1 
    likable_status 
    uid_0: "yes" 
    uid_2: "yes" 
    uid_3: "unknown" 
    uid_2 
    likable_status 
    uid_0: "yes" 
    uid_1: "unknown" 
    uid_3: "yes" 

有了這個如果你想知道哪些用戶uid_2還沒有決定,查詢未知。

終於 - 你可以測試,看看是否存在節點。所以你可以讀一個節點,看它是否是存在的:像

ref = "/user/uid_2/liked/uid_3" 

,如果不存在,那麼...... uid_2沒有喜歡uid_3。

這裏的一些OBJ C代碼(從火力點)

[ref observeEventType:FEventTypeValue withBlock:^(FDataSnapshot *snapshot) { 
    if (snapshot.value == [NSNull null]) { 
    // The value is null 
    } 
}]; 

雖然這個測試單個節點,就看有沒有路徑內再次是微不足道的建設UID的列表,並測試每個裁判它存在。

注意: 磁盤空間很便宜所以不要擔心數據重複;這是NoSQL數據庫的標準做法,也是讓他們快速尖叫的一部分。

更新編輯與真實世界的數據

結構(注意,在每個uid_x;喜歡爲他們喜歡和not_liked誰是他們沒有誰):

users 
    uid_0 
    liked 
     uid_1: "yes" 
    not_liked 
     uid_2: "no" 
     uid_3: "no" 
uid_1 
    liked 
     uid_0: "yes" 
     uid_2: "yes" 
    not_liked 
     uid_3: "no" 
uid_2 
    liked 
     uid_0: "yes" 
     uid_3: "yes" 
    not_liked 
     uid_1: "no" 
uid_3 
    liked 
     uid_1: "yes" 
    not_liked 
     uid_0: "no" 
     uid_2: "no" 

和代碼:

Firebase *ref = [self.myRootRef childByAppendingPath:@"users"]; 

Firebase *userNotLikedRef = [ref childByAppendingPath:@"uid_2/not_liked"]; 

[userNotLikedRef observeEventType:FEventTypeValue withBlock:^(FDataSnapshot *snapshot) { 

    NSLog(@"%@", snapshot.value); 

}]; 

這導致所有不喜歡的uid_2的(uid_1在這種情況下)

一個使用扁平化結構和查詢(請注意,在每個uid_x節點的孩子是誰喜歡他們的UID)

users 
    uid_0 
    uid_2: "yes" 
    uid_3: "yes" 
    uid_1 
    uid_0: "yes" 
    uid_2: "yes" 
    uid_2 
    uid_1: "yes" 
    uid_3: "yes" 
    uid_3 
    uid_0: "yes" 
    uid_1: "yes" 

和查詢

Firebase *ref = [self.myRootRef childByAppendingPath:@"users"]; 

FQuery *q1 = [ref queryOrderedByChild:@"uid_2"]; 
FQuery *q2 = [q1 queryEqualToValue:@"yes"]; 

[q2 observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot *snapshot) { 

    NSLog(@"%@", snapshot.value); 

}]; 

這個結果更加快速的例子在uid中,uid_2喜歡(這是uid_0和uid_1)

+0

我更新了數據和問題,使其更加清晰。對於那個很抱歉。 – rattanak

+0

我對此感到困惑,這整個結構必須是用戶的孩子,每個用戶都會將這些集合中的一個作爲孩子,對嗎? 「喜歡」值是布爾值意味着它是一對一的映射。喜歡誰? –

+0

@Jay,三態結構。例如,如何查詢所有uid_0不喜歡的用戶,換句話說狀態是「否」?我們是否仍然需要循環uid_0-> likable_status的所有子節點,並比較每個user_id值? – rattanak

1

Firebase的查詢功能非常少,根本沒有辦法根據當前的數據結構獲取想要查詢的信息。

你有三個選擇:

  1. 吸了整個用戶收集和弄明白在JavaScript。根據集合的大小,這可能是可行的。只需創建一個userIds數組,然後拼接出用戶喜歡列表中的所有內容。然而,大規模的情況下,這可能是太多的數據,一次拉下來。

  2. 爲此創建和維護一個集合,每當新用戶加入或用戶喜歡另一個集合時更新一個集合,即notliked。這似乎很笨拙。

  3. 在「真實」數據庫的其他位置執行查詢。 Firebase非常適合很多事情,但是如果您需要複雜的查詢,則將其用作主數據存儲是非常困難的。我發現它作爲另一個更強大數據庫的計算數據的前端最有用。它的優勢在於其擴展性和實時更新能力。

+0

我目前正在執行第1步。在每個查詢中都有不必要的用戶檢查。縮放可能是一個問題。在步驟2中,每個用戶都會攜帶一個notLiked集合,這會創建大量重複的數據。 – rattanak

+0

您是否有服務器,或者客戶端是否僅與Firebase進行所有操作? –

+0

此刻沒有服務器。數據結構的改變會有幫助嗎? – rattanak