2015-03-19 3 views
8

Ich benutze eine neue Datenbank von Microsoft namens DocumentDB. Jetzt möchte ich ein Dokument nach ID löschen, aber ich kann nicht herausfinden, wie das geht. Löschen in DocumentDB erfordert Self-Links und sie unterscheiden sich von meinen eigenen IDs. Allerdings frage ich einmal nach dem Dokument, dann werde ich den Selbst Link bekommen. Mit diesem Self Link lösche ich das Dokument.Wie lösche ich alle Dokumente in DocumentDB durch C# code

Jetzt möchte ich alle Dokumente rund 50000 Dokumente in meiner Sammlung löschen.

Müssen Sie jedes Dokument und dann löschen oder eine einfache Methode, um das gleiche zu tun?

Kann es möglich sein?

+2

(in Java) I möchte auch alle Dokumente einer bestimmten Sammlung löschen. Es scheint nicht möglich, SQL-Syntax zu verwenden. Zum Beispiel ist "DELETE FROM WHERE" heute nicht verfügbar. Ich stimme für [dieses Feedback] (http://feedback.azure.com/forums/263030-documentdb/suggestions/6346033-set-based-operations-insert-update-delete) ab, das sich im Status "in review" befindet. Ich möchte die Elternkollektion nicht löschen und neu erstellen: Für mich ist das keine akzeptable Problemumgehung. Ich wäre wirklich glücklich, eine Lösung dafür zu bekommen ... – boly38

Antwort

7

Sie haben Recht, dass das Löschen von Dokumenten einen Verweis auf die Verknüpfung _self des Dokuments erfordert.

Wenn Sie löschen möchten ALLE Dokumente in Ihrer Sammlung - es kann einfacher und schneller zu löschen und die Sammlung neu erstellen. Die einzige Einschränkung besteht darin, dass serverseitige Skripts (z. B. Sprocs, UDFs, Trigger) ebenfalls zur Sammlung gehören und möglicherweise ebenfalls neu erstellt werden müssen.

Update: Ich schrieb eine schnelle gespeicherte Prozedur, die eine Massenlöschung bei einer Abfrage durchführt. Auf diese Weise können Sie Vorgänge zum Löschen von Daten in weniger Netzwerkanforderungen durchführen.

/** 
* A DocumentDB stored procedure that bulk deletes documents for a given query.<br/> 
* Note: You may need to execute this sproc multiple times (depending whether the sproc is able to delete every document within the execution timeout limit). 
* 
* @function 
* @param {string} query - A query that provides the documents to be deleted (e.g. "SELECT * FROM c WHERE c.founded_year = 2008") 
* @returns {Object.<number, boolean>} Returns an object with the two properties:<br/> 
* deleted - contains a count of documents deleted<br/> 
* continuation - a boolean whether you should execute the sproc again (true if there are more documents to delete; false otherwise). 
*/ 
function bulkDeleteSproc(query) { 
    var collection = getContext().getCollection(); 
    var collectionLink = collection.getSelfLink(); 
    var response = getContext().getResponse(); 
    var responseBody = { 
     deleted: 0, 
     continuation: true 
    }; 

    // Validate input. 
    if (!query) throw new Error("The query is undefined or null."); 

    tryQueryAndDelete(); 

    // Recursively runs the query w/ support for continuation tokens. 
    // Calls tryDelete(documents) as soon as the query returns documents. 
    function tryQueryAndDelete(continuation) { 
     var requestOptions = {continuation: continuation}; 

     var isAccepted = collection.queryDocuments(collectionLink, query, requestOptions, function (err, retrievedDocs, responseOptions) { 
      if (err) throw err; 

      if (retrievedDocs.length > 0) { 
       // Begin deleting documents as soon as documents are returned form the query results. 
       // tryDelete() resumes querying after deleting; no need to page through continuation tokens. 
       // - this is to prioritize writes over reads given timeout constraints. 
       tryDelete(retrievedDocs); 
      } else if (responseOptions.continuation) { 
       // Else if the query came back empty, but with a continuation token; repeat the query w/ the token. 
       tryQueryAndDelete(responseOptions.continuation); 
      } else { 
       // Else if there are no more documents and no continuation token - we are finished deleting documents. 
       responseBody.continuation = false; 
       response.setBody(responseBody); 
      } 
     }); 

     // If we hit execution bounds - return continuation: true. 
     if (!isAccepted) { 
      response.setBody(responseBody); 
     } 
    } 

    // Recursively deletes documents passed in as an array argument. 
    // Attempts to query for more on empty array. 
    function tryDelete(documents) { 
     if (documents.length > 0) { 
      // Delete the first document in the array. 
      var isAccepted = collection.deleteDocument(documents[0]._self, {}, function (err, responseOptions) { 
       if (err) throw err; 

       responseBody.deleted++; 
       documents.shift(); 
       // Delete the next document in the array. 
       tryDelete(documents); 
      }); 

      // If we hit execution bounds - return continuation: true. 
      if (!isAccepted) { 
       response.setBody(responseBody); 
      } 
     } else { 
      // If the document array is empty, query for more documents. 
      tryQueryAndDelete(); 
     } 
    } 
} 
+0

Ja, dachte ich auch gleich. Wenn ich die Sammlung lösche, muss ich gespeicherte Prozeduren und Trigger erneut erstellen. Aber wie auch immer, danke, lassen Sie mich wissen, es gibt keinen anderen einfachen Prozess, um alle Datensätze auf einmal zu löschen :) –

+0

ablehnen: keine Antwort dafür: "Dank lassen Sie mich wissen, gibt es keinen anderen einfachen Prozess, um alle Datensätze auf einmal zu löschen" – boly38

+1

FYI - Abstimmung sollte darauf basieren, ob Sie eine genaue Antwort auf die Frage erhalten ... nicht, ob die von Ihnen verwendete Software eine Funktion unterstützt. –

2

Hier ist eine Lösung zum Löschen von Dokumenten mit dem C# SDK. Der folgende Code geht von einer einzelnen Datenbank und einer einzelnen Sammlung aus. Es iteriert alle Dokumente in der Sammlung und löscht sie einzeln. Um bestimmte Datenbanken, Sammlungen oder Dokumente zu löschen, ändern Sie die entsprechende "CreateQuery" -Methode so, dass sie die SQL-Auswahlsyntax enthält. Um zum Beispiel eine bestimmte Datenbank auszuwählen,

db = client.CreateDatabaseQuery().Where(o => o.Id == "MyDocDb").ToList().First();

Beispielcode für alle Dokumente in einem DocumentDB-Instanz mit einer einzigen Datenbank und einer einzigen Sammlung löschen:

using Microsoft.Azure.Documents; 
using Microsoft.Azure.Documents.Client; 
using Microsoft.Azure.Documents.Linq; 
using System; 
using System.Collections.Generic; 
using System.Diagnostics; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace Util 
{ 
    class Program 
    { 
     private Uri _docDbUri = new Uri("https://<nameofyourdocdb>.documents.azure.com:443/"); 
     private string _docDbKey = "<your primary key>"; 

     private async Task DeleteDocsAsync() 
     { 
      using (var client = new DocumentClient(_docDbUri, _docDbKey)) 
      { 
       try 
       { 
        var db = client.CreateDatabaseQuery().ToList().First(); 
        var coll = client.CreateDocumentCollectionQuery(db.CollectionsLink).ToList().First(); 
        var docs = client.CreateDocumentQuery(coll.DocumentsLink); 
        foreach (var doc in docs) 
        { 
         await client.DeleteDocumentAsync(doc.SelfLink); 
        } 
       } 
       catch (Exception ex) 
       { 
        Trace.WriteLine(ex); 
        throw; 
       } 
      } 
     } 



     static void Main(string[] args) 
     { 
      try 
      { 
       Program p = new Program(); 
       p.DeleteDocsAsync().Wait(); 
      } 
      catch (Exception) 
      { 
       throw; 
      } 
     } 
    } 
} 
+0

Dies ist die Methode der Gettiing alle Datensätze und löschen eins nach dem anderen, Danke für Ihre Antwort –

+0

Diese Methode erfordert eine Änderung, der Aufruf von DeleteDocumentAsync erfordert den Partitionsschlüssel als Teil des RequestOptions-Objekts. Ansonsten hat das wirklich geholfen. Vielen Dank. – Yatin

+0

Wenn Sie alle Aufgaben in einer Liste speichern und dann auf alle warten, sparen Sie wahrscheinlich Zeit. oder sogar jede Menge von 100, wenn die Sammlung riesig ist. – Ram