2012-05-14 7 views
7

Patch APIを使用してネストされたコレクションを更新しようとしています。具体的には、以下の例を考える - 投稿コレクション:RavenDB Patch API:ネストされたコレクションの更新

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

を私が集合演算を使用して一括更新を行うにはhttp://ravendb.net/docs/client-api/partial-document-updateshttp://ravendb.net/docs/client-api/set-based-operationsだけでなく、資源としてのいくつかのstackoverflowの質問にパッチのAPIおよびセットベースの操作ドキュメントを使用しました静的なインデックスです。要件は、前の値が「ニース」だった場合にのみコメントの「タイトル」を更新し、そうであれば「不良」に更新することです。

静的インデックス "NicePostsは" のように定義されます。

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

バルクパッチアップデートコマンドは次のとおりです。

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); 

私はこれに関するいくつかの質問があります。

1)私です更新コマンドの構造/構文は正しい?

2)コレクション内のすべてのレコードに対して更新を実行します。したがって、 "NicePosts"インデックスが既に適切なセットを返すため、IndexQueryクエリでクエリフィルタを定義していません。ただし、このコマンドを実行してもコレクションは更新されません。

3) "allowStale:false"を設定した場合、「古いインデックス」エラーが発生します。ドキュメントストアセッションを開く前に、インデックスクラスをインスタンス化し、それを実行してravenDBインスタンスに永続化します。どんなアイデアがここで間違っているの?

おかげで、

EDIT:

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); 

答えて

3

あなたが既存の値に基づいて値を更新するために、patchコマンドを使用することはできません。ayendeの勧告に基づいて

はにパッチコマンドを変更アレイ。 実際の位置を指定する必要があります。

+0

おかげAyende私はそれを認識して波平。私はprevValを削除し、Position = 0を追加して "新しいIndexQuery()"を保持しましたが、値はまだ更新されていません。変更が必要なことは他にありますか?編集したパッチコマンドを元の投稿に追加しました。 – fjxx

+0

私は "new IndexQuery {}"を使用しました。ありがとう! – fjxx

9

これは今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

私は、パッチの要求をスピードアップするために、コメントタイトルでクエリにインデックスを使用します。 JSのすべてのインデックス結果をフィルタリングするよりもクエリが高速です。 – CMircea

+0

これは受け入れられる回答である必要があります – jolySoft

関連する問題