FB & swift verwenden .indexOn zum Sortieren von Daten-snapshot

Ich bin ein FB/swift-Neuling, und ich bin versucht zu verwenden .indexOn zu Sortieren eine Reihe von Knoten auf dem server. Ich habe gesucht und die docs, um die Regeln geschrieben, aber ich habe Mühe mit dem richtigen format für den swift-code der index.

Meine Vermutung ist, dass wenn ich eine .indexOn Regel die zurückgegeben snapshot verwendet diesen index, um, um das Ergebnis. Durch die Nutzung .queryOrderedByChild(„Titel“) im swift-ich Annulliere die server-seitige performance-Vorteile der Erstellung der index. Bitte korrigieren Sie mich, wenn diese Annahme falsch ist.

Hier ist ein vereinfachter Ausschnitt aus meinem FB-DB-Struktur:

{
  "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",
        }
      }
    }
  }
}

Hier ist meine Regel JSON:

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

Hier meine swift-code:

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.
}

Irgendwelche Vorschläge, wie kann ich ändern meine Swift-code zu verwenden, den index (oder die richtigen index-wenn das falsch ist) wäre toll.

  • Ich bin mir nicht ganz klar, auf deine Frage. Sehen Sie negative Auswirkungen auf die Leistung nach dem hinzufügen eines index? Oder sind Ihre Ergebnisse zeigen nicht in Ordnung?
  • Hi @FrankvanPuffelen – Bedenken Sie, ich bin ein Neuling, also ich bin ein wenig verwirrt. Meine Ergebnisse sind aktuell in der Reihenfolge, wie Sie gespeichert sind in Feuerstellung, nicht sortiert nach dem index. Ich lese in den docs, dass es besser war, zu tun, die Sortierung auf dem server verwenden .indexOn so entschieden zu tun, dass im Vorfeld (mein Datensatz ist wahrscheinlich ziemlich groß), so dass ich kann nicht kommentieren Leistung in diesem Stadium.
  • OK, habe es. Ich schreib dir eine Antwort. Für die Fragen der Zukunft ist es wahrscheinlich am besten, erwähnen nur den Teil, der falsch läuft. Wenn die Elemente im array werden nicht in der Reihenfolge, die Sie erwartete Auswirkungen auf die Leistung durch die Verwendung eines Indexes sind irrelevant
  • danke. Ich verstehen Sie Ihren Punkt. Allerdings, da bin ich ein verwirrter Neuling, ich bin mir nicht sicher, ob meine indexOn falsch ist, oder ob auch mit der indexOn richtig anstelle, sollte ich noch mit .queryOrderedByChild() irgendwie sehen die Ergebnisse in der erwarteten Reihenfolge Sortieren. Ich nehme an, mein F könnte sein: „nicht mit ein .indexOn in den Regeln JSON entfernen Sie die Notwendigkeit, zu verwenden .queryOrderedByChild (), die beim abrufen von Daten sortiert?“
  • Das Letzte ist in der Tat eine sehr klare Frage. Die Antwort ist „Nein“. Beantworten Sie unten. Jad ‚ s ist den ersten, aber dann müssen Sie wahrscheinlich auch meins.
InformationsquelleAutor James | 2016-07-08



2 Replies
  1. 2

    Müssen Sie queryOrderedByChild, wenn man die Daten anfordert und ein Schlüssel in Ihr Regeln, wie Sie es Tat. hier ist ein Beispiel;

    FB Dokumentationen

    Im folgenden Beispiel wird veranschaulicht, wie konnte Sie abrufen eine Liste von Benutzer-top-Beiträge, sortiert nach Sterne-count:

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

    Diese Abfrage ruft der Nutzer die Einträge aus dem Pfad in der Datenbank, basierend auf Ihrer Benutzer-ID, sortiert nach der Anzahl der Sterne in jedem post erhalten hat. Diese Technik der Verwendung von IDs als index-Schlüssel als data-fan.

    Den Aufruf der queryOrderedByChild Methode gibt die Kind-Schlüssel, um die Reihenfolge der Ergebnisse durch. In diesem Fall werden die Beiträge sortiert nach dem Wert des „starCount“ Kind in jedem post. Für mehr Informationen darüber, wie andere Datentypen werden bestellt, um zu sehen, Wie die Abfrage der Daten bestellt ist.

    Bitte Folgen Sie dem link für weitere details;

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

    • Vielen Dank – ich denke, meine Verwirrung ergibt sich aus der Tatsache, dass ich Lesen Sie in der Dokumentation, dass das hinzufügen eines index zu den Regeln ist eine gute Idee. Ich bin daher davon ausgegangen, dass ein index, statt zu verwenden .queryOrderedByChild(). Wie @FrankVanPuffelen hat bestätigt, dass Ihre Antwort richtig ist, werde ich Ihren Rat befolgen und weiterziehen. Vielen Dank
  2. 2

    First off, müssen Sie Jad Antwort und geben Sie die Reihenfolge, in der Sie empfangen möchten, die untergeordnete Knoten. Eine einzelne Liste kann beliebig viele Indizes, und Sie müssen angeben, in welcher Reihenfolge Sie wollen für diese bestimmte Abfrage.

    Nachdem Sie eine Bestellung, die FB-Datenbank liefert einen snapshot zurück, enthält die Knoten, die mit Ihrer Suchanfrage übereinstimmen und Informationen über die Reihenfolge, in der die Knoten in den Ergebnissen angezeigt.

    Aber ein Wörterbuch hat keine Informationen über die Reihenfolge der Kinder. Also bei deinem code wandelt den snapshot in einem Wörterbuch, alle Informationen über die Reihenfolge verloren:

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

    Aus diesem Grund ist es am besten, um die snapshot-integrierte Methode zum Durchlaufen der child-Knoten:

    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
    }
    • Vielen Dank für die Bestätigung Jad Antwort und für den Tipp über Wörterbücher. Ich bin mir immer noch nicht sicher, wo der client-seitigen performance-Vorteile der addition der index-kommen aus, wenn der client zum Sortieren der Ergebnisse nach eintreffen, aber ich werde weitermachen 🙂
    • Wenn der client nicht um Sie, es gibt einfach zurück, Sie in der richtigen Reihenfolge. Ein Wörterbuch ist ungeordnet, so dass mit der Umstellung auf ein Wörterbuch, das Sie werfen die ganze Bestellung Weg.
    • basierend auf dem code des OP, wenn ich versuche zu Lesen, die Datenbank mithilfe des Swift-Bibliothek ( nicht über REST-API), muss ich noch ändern müssen, um die REGELN in der Feuerstellung Echtzeit-Datenbank, so dass die Leistung von queering verbessert?

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.