2016-04-10 2 views
1

Für eine Anwendung habe ich eine JavaScript-gespeicherte Proc erstellt, um auf AzureDB zu laufen, so dass ich eine Reihe von umfassenden Summierungen erhalten kann, kann ich dann shgow auf meinem Bildschirm.DocumentDb on Azure - ich kann das vollständige Re-Cord-Set in einem einzelnen Lauf nicht abrufen?

Allerdings ist die Anzahl immer ausgeschaltet, es schien, als ob ich nie das vollständige Recordset bekommen würde.

Also habe ich einen Test gemacht. Ich erstellte den folgenden gespeicherten proc:

function trialRun(startDateTime, endDateTime) 
{ 
    var context = getContext(); 
    var collection = context.getCollection(); 
    var response = context.getResponse(); 

    var sqlString = "select p.id, p.ClientId, p.ActionType, a.Action, a.TimeStamp " 
        + "from History p" 
        + "  join a in p.Actions " 
        + "where a.TimeStamp >= '" + startDateTime + "' " 
        + " and a.TimeStamp <= '" + endDateTime + "' "; 

    // Query documents 
    var isAccepted = collection.queryDocuments(collection.getSelfLink(), sqlString, 
               function (err, feed, options) 
               { 
                if (!err) 
                { 
                 response.setBody(JSON.stringify(feed)); 
                } 
                else 
                { 
                 throw err; 
                } 
               }); 

    if (!isAccepted) { throw new Error("The query was not accepted by the server."); } 
} 

Und in der Tat, vermisst der Ausgang 10 Datensätze.

Ich lese über Paging und so ... aber ich habe bisher nichts zu diesem Problem gefunden.

Wer hier könnte mich in die richtige Richtung bringen? Vielleicht ein Beispielcode, um die Daten von der nächsten "Seite zu bekommen?

Antwort

1

Zuerst eine Empfehlung. Wenn alles, was Sie tun, eine Abfrage ist, sind Sie besser dran mit dem Client-Side-SDK und/oder documentdb-utils (die ist nur ein Wrapper für das von Azure bereitgestellte SDK. Abfragen in einem Sproc verwenden keine Secondaries und begrenzen den Gesamtdurchsatz. Abfragen vom Client-SDK verwenden Secondaries und sind leistungsfähiger. Wenn Sie andererseits aggregieren, a Reihen von Zeilen bis zu einem einzigen Ergebnis, dann könnte ein Sproc am besten sein, je nachdem.

Das heißt, selbst wenn Sie Ihre Aggregation in die Sproc verschieben, haben Sie das gleiche Problem. Also, um das zu beheben, Sie Vielleicht möchten Sie eines der Beispiele in documentdb-utils ansehen: Beginnen Sie mit der countDocuments Sproc. Vielleicht möchten Sie auch das Muster für das Schreiben von neustartbaren Sprocs kennen lernen, die gefunden wurden here. Das Schlüsselkonzept, von dem ich vermute, dass Sie fehlen, ist, dass Sie in einer NoSQL-Welt und insbesondere mit JavaScript asynchron denken und Ihren Code schreiben müssen, damit er unterbrochen und neu gestartet werden kann.

Unter der Annahme, dass Sie Ihre Aggregation muss in das sproc bewegen kann, Änderungen an Ihr benötigt als schriftliche sind:

  1. keinen Fehler werfen Sie, wenn das System die Annahme von Anfragen stoppt. Speichern Sie stattdessen den aktuellen Ausführungsstatus und fügen Sie einen Indikator hinzu, dass der SPROC neu gestartet werden muss. Das countDocuments-Beispiel, mit dem ich verknüpft habe, verwendet stillQueueing. Wenn Sie documentdb-utils verwenden, sagt das, dass der Sproc nicht ausgeführt wurde und erneut aufgerufen werden muss.

  2. für requestOptions einen dritten Parameter zu Ihrem queryDocuments() Anruf hinzufügen und setzen pageSize bis 1000. 1000 es ist groß genug, dass man nicht eine Tonne von Rundreisen in die Datenbank haben, aber klein genug, dass man sie verarbeiten kann nachdem das System einen false zurückgibt, der anzeigt, dass Anfragen nicht mehr in die Warteschlange gestellt werden, aber bevor das Zeitlimit für den Sproc überschritten wird.

  3. Da die Seiten kommen, machen Sie Ihre Aggregation und sammeln das Ergebnis im Körper, den Sie zurückgeben werden.

  4. Sie müssen die Antwort nicht JSON.stringify(). Das System kümmert sich um das Marshalling einfacher JavaScript-Objekte.

  5. In jedem Fall kleben Sie nicht den gesamten Feed in Ihre Antwort. Nur deine Aggregation.

  6. Erfassen Sie das Fortsetzungs-Token, das im dritten options-Parameter des Rückrufs gefunden wurde, und geben Sie es mit Ihrer Antwort zurück.

Wenn Sie wirklich eine sproc und kehren alle Zeilen anstatt das Client-SDK oder eine sproc mit nur Aggregation verwenden wollen, dann muss ich Sie warnen, aus documentdb-utils zu verwenden. Wenn Sie den gesamten Feed in die Antwort stecken, wird er versuchen, ihn für jede Runde hin und her zu senden und schnell die maximale Nutzlast für einen Sproc-Aufruf oder eine Rückgabe zu überschreiten. Sie könnten jedoch das Raw-SDK verwenden und sicherstellen, dass die Feed-Inhalte entfernt werden, bevor Sie zu einem anderen Anruf zurückkehren.

+0

Nun, es war nur ein schneller Test. Ich wollte sehen, welche Datensätze mein gespeicherter Proc durchlaufen hat. – Fysicus

+0

In meinem tatsächlichen Stored Proc durchlaufe ich den Feed und erstelle ein paar Wörterbuchobjekte; Das sind die Objekte, die ich stringify und dann wieder an den Client senden. – Fysicus

+0

Ich vermutete, dass Sie tatsächlich eine Aggregation erstellen möchten. :-) Trotzdem musst du sie nicht stringieren. Gib einfach die JavaScript-Objekte zurück. Die Sache, die fehlt, ist eine Möglichkeit, für mehr Seiten zurückzukehren. –

0

Nun, ich habe eine Kombination aus Ihrer Antwort und die Probe gespeicherte Prozedur getan, was ich auf GitHub gefunden

diese unter Verwendung von 2 als Referenzen, die ich meine ‚trial gespeicherte Prozedur wie folgt überarbeitet:

function trialRun(startDateTime, endDateTime, continuationToken) 
{ 
    var context = getContext(); 
    var collection = context.getCollection(); 
    var maxResult = 1000; // Value from sample = 25 

    var sqlString = "select p.id, p.ClientId, p.ActionType, a.Action, a.TimeStamp " 
        + "from History p" 
        + "  join a in p.Actions " 
        + "where a.TimeStamp >= '" + startDateTime + "' " 
        + " and a.TimeStamp <= '" + endDateTime + "' "; 
    var result = null; 

    tryQuery(continuationToken, sqlString); 

    // Helper method to check for max result and call query. 
    function tryQuery(nextContinuationToken) 
    { 
     var responseOptions = { continuation: nextContinuationToken, pageSize : maxResult }; 

     // In case the server is running this script for long time/near timeout, it would return false, 
     // in this case we set the response to current continuation token, 
     // and the client will run this script again starting from this continuation. 
     // When the client calls this script 1st time, is passes empty continuation token. 
     if (result >= maxResult || !query(responseOptions)) { setBody(nextContinuationToken); } 
    } 

    function query(responseOptions) 
    { 
     var resultSet = collection.queryDocuments(collection.getSelfLink(), sqlString, responseOptions, onReadDocuments); 

     return resultSet; 
    } 

    function onReadDocuments(err, docFeed, responseOptions) 
    { 
     if (err) 
     { 
      throw 'Error while reading document: ' + err; 
     } 

     // Increament the number of documents counted so far. 
     result += JSON.Stringify(docFeed); 

     // If there is continuation, call query again with it, 
     // otherwise we are done, in which case set continuation to null. 
     if (responseOptions.continuation) 
     { 
      tryQuery(responseOptions.continuation); 
     } 
     else 
     { 
      setBody(null); 
     } 
    } 

    // Set response body: use an object the client is expecting (2 properties: result and continuationToken). 
    function setBody(continuationToken) 
    { 
     var body = { trialRun: result, continuationToken: continuationToken }; 
     getContext().getResponse().setBody(body); 
    } 
} 

Jetzt enthält die Ergebnismenge, die ich erhalte, die fehlenden 10 Datensätze. Ich überarbeite meine eigentliche Prozedur auf die gleiche Weise.

+0

Ich weiß, ich bin immer noch mit einem 'JSON.stringify' Anruf hier. Aber mir ist noch nicht klar, wie ich die neu erstellten Objektdaten zu der bereits vorhandenen Ergebnismenge "hinzufügen" kann. – Fysicus

+0

Sie können das Array, das Sie zuvor erstellt haben, mit jeder weiteren Seite verketten. –

+0

Und ein Wörterbuch? – Fysicus

Verwandte Themen