7

Cảnh báo:Cách thể hiện mối quan hệ hai chiều trong cây JSON Firebase?

  • đây là một bài tập để hiểu rõ hơn về thiết kế cơ sở dữ liệu JSON trong Firebase
  • nó không nhất thiết phải thực tế

tôi đã có một mối quan hệ hai cách giữa người sử dụng và các phím cửa. Tôi muốn hiểu:

  • làm thế nào để đại diện cho mối quan hệ này bằng mắt (tôi có thể tưởng tượng nó chỉ như là hai cây riêng biệt)
  • cách này sẽ làm việc trên căn cứ hỏa lực, sẽ cả người dùngdoor- phím là con của nút cha "myparentnodename"?
  • Nếu tôi mô hình hóa cơ sở dữ liệu theo cách này, nó cảm thấy rất không hiệu quả bởi vì mỗi lần tôi truy vấn nút con "người dùng", tôi sẽ lấy lại tất cả người dùng. Hoặc là tôi sai? Có thể chỉ lấy lại dữ liệu phù hợp với một người dùng cụ thể không? Ví dụ. có được người dùng ở đâu "user = user1"? Chúng tôi có thể thực hiện các truy vấn lồng nhau không? ví dụ. kết hợp điều kiện trước đó với một số điều kiện trên các phím cửa sao cho đối tượng JSON trả lại chỉ liên quan đến các khóa cửa chứa trong nút "user1"?

enter image description here

Trả lời

10

Đây là một câu trả lời rất dài như câu hỏi của bạn thực sự là khoảng 5 câu hỏi khác nhau.

nút gốc là: myparentnodename

Người dùng của bạn

users 
    uid_0 
     name: "William" 
     door_keys: 
     key_0: true 
     key_3: true 
    uid_2 
     name: "Leonard" 
     door_keys: 
     key_3: true 
     key_5: true 

và các phím của bạn

keys 
    key_0 
     uid_0: true 
    key_3 
     uid_0: true 
     uid_2: true 
    key_5 
     uid_5: true 

Với cấu trúc này, tất cả các yếu tố 'điểm' nhau.

Nếu bạn truy vấn uid_0 bạn có thể thấy rằng họ sử dụng các phím 0 và 3

Nếu bạn truy vấn key_3 bạn có thể thấy họ thuộc về người sử dụng 0 và 2

Câu hỏi của bạn là

mỗi thời gian tôi sẽ truy vấn nút con "người dùng" tôi sẽ nhận được tất cả người dùng quay lại

Đó là một chút không đầy đủ . Khi một truy vấn được thực hiện, bạn thường truy vấn một cái gì đó cụ thể. Tuy nhiên, với Firebase, có hai cách để truy xuất dữ liệu: quan sát một nút và một truy vấn.

Nếu bạn muốn quay lại tất cả người dùng trong nút người dùng, bạn sẽ quan sát nút đó theo .Value (hoặc .ChildAdded cho 1 tại một thời điểm).

ref = myParentNodeName 
let usersRef = myParentNodeName.childByAppendingPath("users") 

usersRef.observeEventType(.Value, withBlock: { snapshot in 

    //.Value can return multiple nodes within the snapshot so iterate over them 
    for child in snapshot.children { 
     let name = child.value.objectForKey("name") as! String 
     print(name) //prints each users name 
    } 
}) 

lưu ý rằng gắn trên một quan sát viên đến nút người sử dụng vì vậy bất kỳ sự thay đổi tương lai trong nút đó sẽ thông báo cho các ứng dụng và gửi lại toàn bộ nút để ứng dụng

Nếu bạn muốn chỉ là một thông tin của người dùng , và không muốn tiếp tục xem các thay đổi

ref = myParentNodeName 
let usersRef = myParentNodeName.childByAppendingPath("users") 
let thisUserRef = usersRef.childByAppendingPath("uid_2") 
thisUserRef.observeSingleEventOfType(.Value, withBlock: { snapshot in 

    let name = child.value.objectForKey("name") as! String 
    print(name) //prints each users name 
}) 

Cuối cùng, để truy vấn cho tất cả các phím thuộc về uid_0 (mà là một dư thừa chút trong ví dụ này vì chúng ta đã biết các phím họ có từ nút của họ) . Nếu các phím ref cũng chứa thông tin khác như tên cửa, tòa nhà cửa đang ở, hoặc vị trí cửa ra vào, nó sẽ thích hợp hơn và sẽ yêu cầu một cấu trúc khác nhau, vì vậy giả định đó là trường hợp:

ref = myParentNodeName 
let keysRef = myParentNodeName.childByAppendingPath("keys") 

keysRef.queryOrderedByChild("uid_0").queryEqualToValue(true) 
    .observeSingleEventOfType(.Value, withBlock: { snapshot in 

     let doorLocation = child.value.objectForKey("door_location") as! String 
     print(doorLocation) //prints each users name 
}) 

lưu ý mã này là Swift vì nền tảng không được chỉ định trong câu hỏi.

Một câu hỏi khác:

Chúng ta có thể làm lồng nhau truy vấn? ví dụ. kết hợp điều kiện trước với một số điều kiện trên các phím cửa sao cho đối tượng JSON được trả lại chỉ là liên quan đến các khóa cửa có trong nút "user1"?

Tôi nghĩ bạn có nghĩa là bạn có thể truy vấn uid_2, xem khóa nào họ có và sau đó tải thông tin từ các khóa cụ thể đó.

Có! Nhưng ... (luôn có một nhưng)

Firebase là không đồng bộ, do đó bạn phải tính đến điều đó khi lồng truy vấn tức là bạn cần đảm bảo tất cả dữ liệu được trả lại trước khi nhận thêm dữ liệu. Vì vậy, ví dụ: nếu bạn muốn uid_2 dữ liệu chính, bạn có thể quan sátSingleEventOfType trên nút uid_2. Sau đó, bạn sẽ có khóa của họ và sau đó có thể quan sátSingleEventOfType trên mỗi khóa.

Về mặt kỹ thuật, thao tác này sẽ hoạt động nhưng với dữ liệu không đồng bộ đang bay xung quanh, bạn có thể kết thúc với mã stomping trên mã khác và xử lý dữ liệu trước khi thực sự được trả lại.

Tùy chọn tốt hơn (theo ví dụ của tôi) là chỉ cần tránh điều đó hoàn toàn và truy vấn nút khóa cho các khóa của uid_2.

Như một lưu ý phụ, việc quan sát một nút có chi phí thấp hơn rất nhiều so với truy vấn vì vậy nếu bạn muốn tải một nút duy nhất và bạn biết đường dẫn, hãy sử dụng quan sát.

Các vấn đề liên quan