2012-05-14 13 views
7

Sto tentando di aggiornare una raccolta nidificata utilizzando l'API Patch. Più in particolare, si consideri il seguente esempio - una collezione Messaggi:API Patch RavenDB: aggiornamento di una raccolta nidificata

{ 
    "Title": "Hello RavenDB", 
    "Category": "RavenDB", 
    "Content": "This is a blog about RavenDB", 
    "Comments": [ 
    { 
     "Title": "Unrealistic", 
     "Content": "This example is unrealistic" 
    }, 
    { 
     "Title": "Nice", 
     "Content": "This example is nice" 
    } 
    ] 
} 

ho usato l'API Patch e documenti operativi basati su Set a http://ravendb.net/docs/client-api/partial-document-updates e http://ravendb.net/docs/client-api/set-based-operations così come diverse domande StackOverflow come risorse per fare un aggiornamento di massa usando le operazioni di set e un indice statico. Un requisito è aggiornare il "Titolo" di un commento solo quando il valore precedente era "Bello" e, in tal caso, aggiornarlo su "Cattivo".

L'indice statici "NicePosts" è definito come:

Map = posts => from post in posts  
       where post.Comments.Any(comment => comment.Title == "Nice") 
       select new {post.Title, post.Category} 

Il comando di massa patch di aggiornamento è:

documentStore.DatabaseCommands.UpdateByIndex("NicePosts", 
        new IndexQuery(),            
      new[] { new PatchRequest 
        { Type = PatchCommandType.Modify,       
        Name = "Comments", 
         PrevVal = RavenJObject.Parse(@"{ ""Title"": ""Nice""}"), 
         Nested = new[] 
           { 
           new PatchRequest {Type = PatchCommandType.Set, Name = "Title", Value = new RavenJValue("Bad") }, 
         } }, allowStale: true); 

Ho alcune domande riguardo a questa:

1) è il mio struttura/sintassi per il comando di aggiornamento corretti?

2) Desidero che l'aggiornamento venga eseguito su tutti i record della raccolta. Quindi non ho definito il filtro di query nella query IndexQuery perché l'indice "NicePosts" restituisce già il set appropriato. Tuttavia, l'esecuzione di questo comando non aggiorna la raccolta.

3) Se si imposta "allowStale: false", viene visualizzato un errore "indice scaduto". Prima di aprire la sessione del mio archivio documenti, istanzia la classe index e la eseguo per mantenerla nell'istanza ravenDB. Qualche idea che sta andando storto qui?

Grazie,

EDIT:

basata sulla raccomandazione di Ayende cambiato comando patch a:

documentStore.DatabaseCommands.UpdateByIndex("NicePosts", 
             new IndexQuery(), 
             new[] { 
                new PatchRequest { 
                Type = PatchCommandType.Modify, 
                Name = "Comments", 
                Position = 0, 
                Nested = new[] { 
                 new PatchRequest {Type = PatchCommandType.Set, Name = "Title", Value = new RavenJValue("Bad")}, 
                } 
                } 
               }, allowStale: false); 

risposta

3

Non è possibile utilizzare il comando patch per aggiornare i valori in base al valore esistente nella array. È necessario specificare la posizione attuale.

+0

Grazie Ayende Non ero a conoscenza di esso. Ho rimosso prevVal e aggiunto Position = 0 e mantenuto "new IndexQuery()" ma il valore non è ancora in fase di aggiornamento. C'è qualcos'altro che deve cambiare? Ho aggiunto il comando patch modificato nel post originale. – fjxx

+0

Ho appena usato "nuova IndexQuery {}" e tutto funziona ora. Grazie ! – fjxx

9

Questo può ora essere fatto utilizzando il scripted patch request:

string oldTitle = "Nice"; 
string newTitle = "Bad"; 

documentStore.DatabaseCommands.UpdateByIndex("NicePosts", 
    new IndexQuery(),            
    new ScriptedPatchRequest 
    {      
     Script = @"for (var i = 0; i < this.Comments.length; i++) 
         if (this.Comments[i].Title == oldTitle) 
          this.Comments[i].Title = newTitle;", 
     Values = 
     { 
      { "oldTitle", oldTitle }, 
      { "newTitle", newTitle }, 
     }, 
    } 
); 
+0

Vorrei usare un indice per interrogare il titolo del commento per accelerare la richiesta di patch; è più veloce interrogare che filtrare tutti i risultati dell'indice in JS. – CMircea

+0

Questa dovrebbe essere la risposta accettata – jolySoft

Problemi correlati