2016-07-08 1 views
1

저는 Firebase/swift 초보자이며 .indexOn을 사용하여 서버의 노드 집합을 정렬하려고합니다. 나는 SO와 문서를 검색하여 규칙을 작성했지만 신속한 코드가 색인을 사용하기위한 올바른 형식으로 고민하고 있습니다.데이터베이스를 정렬하려면 .indexOn을 사용하십시오.

내 가정은 .indexOn 규칙을 사용할 때 반환 된 스냅 샷은 해당 인덱스를 사용하여 결과를 정렬한다는 것입니다. swift에서 .queryOrderedByChild ("title")을 사용함으로써 인덱스를 생성 할 때의 서버 측 성능 이점을 무효화합니다. 이 가정이 부정확하면 저를 시정하십시오.

{ 
    "rules": { 
     ".read": true, 
     ".write": true, 
     "users": { 
       "$userid": { 
        "messages": { 
          ".indexOn": ["title"] 
        } 
       } 
     } 
    } 
} 

가 여기 내 SWIFT 코드입니다 :

{ 
    "users": { 
    "GkdjgdBJh1TxuAzIPezLWRouG9f2": { 
     "messages": { 
     "-KM0crettRl-RLQQdmMQ": { 
      "body": "Anyone want a bit of body string?", 
      "title": "5 Another title string", 
     }, 
     "-KM0dhkChY6ZQ2QzuPlC": { 
      "body": "This is a short body string", 
      "title": "1 A lovely title string", 
     }, 
     "-FQ0dhkChY6ZQ2Qzu3RQv": { 
      "body": "Short and sweet body string", 
      "title": "3 I should be in the middle", 
     } 
     } 
    } 
    } 
} 

가 여기 내 규칙 JSON입니다 : 여기

내 중포 기지 DB 구조의 단순화 된 조각의

if let user = FIRAuth.auth()?.currentUser { 
    // user is logged in 

    // *** I think this is the line with the issue *** 
    FIRDatabase.database().reference().child("users").child(user.uid).child("messages").observeEventType(.Value, withBlock: { (snapshot) in 
    messageArray = [] 

     if let dictionaryOfMessages = snapshot.value as? [String: AnyObject] { 
      for messageKey in dictionaryOfMessages.keys { 
       messageArray.append(Message(json: JSON(dictionaryOfMessages[messageKey]!))) 
       // set the messageId 
       messageArray[messageArray.count - 1].messageId = messageKey 
      } 
     } 
     // return the data to the VC that called the function 
     success(messages: messageArray) 
    }) { (error) in 
     // Handle the Error 
    } 
} else { 
    // return some generic messages about logging in etc. 
} 

모든 제안을 어떻게 할 수 내 Swift 코드를 수정하여 색인을 사용하거나 잘못 되었다면 색인을 수정하십시오.

+0

귀하의 질문에 완전히 명확하지 않습니다. 색인을 추가 한 후 성능에 부정적인 영향을 미치고 있습니까? 또는 결과가 잘못 표시됩니까? –

+0

안녕하세요 @ FrankvanPuffelen - 나는 조금 혼란스러워하므로 초보자입니다. 내 결과는 현재 색인에 따라 정렬되지 않고 Firebase에 저장된 순서대로 표시됩니다. 필자는 문서에서 .indexOn을 사용하여 서버에서 정렬하는 것이 더 낫다는 것을 알았으므로이 단계에서 성능에 대해 언급 할 수 없도록 (데이터 세트는 꽤 커질 수 있습니다) 앞쪽으로하기로 결정했습니다. – James

+0

OK, 알겠습니다. 나는 대답을 쓸 것이다. 미래의 질문에 대해서는 잘못된 부분 만 언급하는 것이 가장 좋습니다. 배열의 요소가 예상 한 순서대로 정렬되지 않은 경우 색인을 사용하면 성능에 미치는 영향은 부적절합니다. –

답변

2

데이터를 요청할 때 queryOrderedByChild을 사용해야하고 이전처럼 규칙에 키가 있어야합니다. 여기에 예제가있다;

// My top posts by number of stars 
let myTopPostsQuery = (ref.child("user-posts").child(getUid())).queryOrderedByChild("starCount") 

이 쿼리의 경로에서 사용자의 게시물을 검색합니다

중포 기지 문서화

다음 예제는 계산 자신의 성으로 분류되어 사용자의 상위 게시물의 목록을 검색하는 방법을 보여줍니다 데이터베이스는 사용자 ID를 기반으로 각 게시물이 수신 한 별의 수를 기준으로 정렬됩니다. ID를 색인 키로 사용하는이 기술을 데이터 팬 아웃이라고합니다.

queryOrderedByChild 메소드를 호출하면 결과를 정렬 할 하위 키가 지정됩니다. 이 경우 게시물은 각 게시물의 "starCount"하위 값에 따라 정렬됩니다. 다른 데이터 형식의 정렬 방법에 대한 자세한 내용은 쿼리 데이터의 정렬 방법을 참조하십시오.

자세한 내용은 링크를 클릭하십시오.

https://firebase.google.com/docs/database/ios/retrieve-data

+0

감사합니다. 내 혼란은 규칙에 색인을 추가하는 것이 좋은 아이디어라는 것을 문서에서 읽었 기 때문에 발생한다고 생각합니다. 따라서 색인은 .queryOrderedByChild()를 사용하는 대신 * 것으로 가정했습니다. @FrankVanPuffelen이 귀하의 답변이 정확한지 확인한대로, 귀하의 조언을 따르고 계속 진행할 것입니다. 많은 감사합니다 – James

2

우선 해제, 당신은 애플 리케이션 설계의 답변을 따라 당신은 자식 노드를 수신 할 순서를 지정해야합니다. 단일 목록에는 많은 색인이있을 수 있으므로이 특정 조회에 대해 원하는 순서를 지정해야합니다.

주문을 지정한 후 Firebase 데이터베이스는 쿼리와 일치하는 노드와 그 노드가 결과에 나타나는 순서에 대한 정보를 포함하는 스냅 샷을 반환합니다.

그러나 사전에는 어린이 주문에 대한 정보가 없습니다.코드가 사전에 스냅 샷을 변환 때, 순서에 대한 모든 정보가 손실됩니다 :

if let dictionaryOfMessages = snapshot.value as? [String: AnyObject] { 

는 자식 노드 반복에 대한 스냅 샷에 내장 된 방법을 사용하는 것이 가장 좋습니다 이런 이유로 :

for child in snapshot.children { 
    let key = child.key as String 
    print(key) 
    messageArray.append(Message(json: JSON(child.value))) // JSON handling via SwiftyJSON 
    // set the messageId 
    messageArray[messageArray.count - 1].messageId = key 
} 
+0

Jad의 답변을 확인하고 사전에 대한 팁 주셔서 감사합니다. 클라이언트가 도착한 후에 결과를 주문해야한다면 인덱스를 추가하는 클라이언트 측 성능 이점은 어디에서 왔는지는 확실하지 않지만 계속 진행할 것입니다 :-) – James

+1

클라이언트가 클라이언트를 주문하지 않습니다. 올바른 순서로 반환합니다. 사전은 순서가 지정되지 않으므로 사전으로 변환하면 모든 주문을 버리게됩니다. –

+0

OP의 코드를 기반으로 한 @FrankvanPuffelen, Swift 라이브러리 (REST API를 사용하지 않음)를 사용하여 데이터베이스를 읽으려는 경우, Queering의 성능이 향상되도록 Firebase Real Time Database의 규칙을 수정해야합니까? – bibscy

관련 문제