2012-05-14 2 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" 
    } 
    ] 
} 

Я использовал патч API и операции документы Set основанные на http://ravendb.net/docs/client-api/partial-document-updates и http://ravendb.net/docs/client-api/set-based-operations, а также несколько вопросов StackOverflow как ресурсов для выполнения массового обновления с использованием наборов операций и статический индекс. Требование состоит в том, чтобы обновить «Заголовок» комментария только тогда, когда предыдущее значение было «Ницца», и если да, обновите его до «Плохо».

статического индекса "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) Является ли мой структура/синтаксис для команды update правильно?

2) Я хотел бы, чтобы обновление выполнялось по всем записям в коллекции. Следовательно, я не определил фильтр запросов в запросе IndexQuery, потому что индекс «NicePosts» уже возвращает соответствующий набор. Однако выполнение этой команды не обновляет коллекцию.

3) Если я устанавливаю «allowStale: false», я получаю ошибку «устаревший индекс». Перед открытием сеанса хранилища документов я создаю экземпляр класса индекса и выполняю его, чтобы сохранить его в экземпляре ravenDB. Какие-нибудь идеи, что здесь происходит?

Спасибо,

EDIT:

По рекомендации Ayende изменилась команда Patch на:

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

Вы не можете использовать команду патч для обновления значений на основе существующего значения в массив. Необходимо указать фактическое положение.

+0

Спасибо Ayende Я не был в курсе этого. Я удалил prevVal и добавил Position = 0 и сохранил «новый IndexQuery()», но значение все еще не обновляется. Есть ли что-то еще, что нужно изменить? Я добавил отредактированную команду исправления в исходное сообщение. – fjxx

+0

Я просто использовал «новый 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

Смежные вопросы