RavenDB 迁移:将 属性 从字符串更新为字符串数组
RavenDB Migration: update property from string to array of strings
我有一个名为 Actions 的文档集合。数据库中的操作如下所示:
{
"Name": "Name1",
"ActionType": "typeA"
}
我需要迁移所有 Action,这样 ActionType 属性 就会包含一个字符串数组:
{
"Name": "Name1",
"ActionType": ["typeA"]
}
我不想像提到的那样在我的项目中创建任何转换器 here。
那应该是一个简单的实用程序,可以单独运行。
想法是加载所有文档,进行必要的更改并保存它们(如 here)。我当前的代码看起来像这样,但它不能正常工作:
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Raven.Client;
using Raven.Client.Document;
using Raven.Client.Linq;
using Raven.Json.Linq;
namespace RavenDbMigration
{
public class SimpleMigrator
{
private readonly IDocumentStore _documentStore;
public SimpleMigrator(IDocumentStore documentStore)
{
_documentStore = documentStore;
}
public void Run()
{
using (IDocumentSession session = _documentStore.OpenSession())
{
var fullRavenIdsList = new List<string> {"1", "2", "3"};
RavenJObject[] ravenJObjects = session.Load<RavenJObject>(fullRavenIdsList); // Problem here - ravenJObjects contains 3 null values instead of actions
foreach (var ravenJObject in ravenJObjects)
{
var results = ravenJObject["Actions"] as RavenJArray;
if (results != null)
{
foreach (var result in results)
{
if (result != null && result.ContainsKey("ActionType"))
{
var actionTypes = new List<string>();
var actionType = result.Value<string>("ActionType");
if (actionType != null)
{
actionTypes.Add(actionType);
}
result["ActionType"] = new RavenJArray(actionTypes);
}
}
}
}
session.SaveChanges();
}
}
}
}
我使用 RavenDB.Client 版本 2.5.2700。
您需要创建一个类型为 List 的新字段,然后将数据迁移到列表中,而且您没有分页,因此您需要分页以获取所有数据才能为所有记录工作。
之后,您从模型中删除旧的单个字符串 属性,然后当您的数据进行更多更新等时,这个 属性 将被删除。
或
你按照他们告诉你的方式去做,在 link 提供的情况下,创建那个 post 的人拥有 RavenDB 并且知道他在说什么,如果他说这是最好的方法,你通常可以保证它是。
您可以通过 Raven Studio 或代码修补文档集 "Actions"。
this.ActionType = [this.ActionType];
这将导致文档如下所示:
"Name": "Name1",
"ActionType": [
"typeA"
]
希望这对您有所帮助!
如果有人对如何从代码执行此迁移感兴趣,请查看示例代码:
using System.Collections.Generic;
using System.Linq;
using Raven.Client;
using Raven.Client.Linq;
using Raven.Imports.Newtonsoft.Json.Linq;
using Raven.Json.Linq;
namespace RavenDbMigration
{
public class SimpleMigrator
{
private readonly IDocumentStore _documentStore;
private readonly int _pageSize;
public SimpleMigrator(IDocumentStore documentStore, int pageSize = 128)
{
_pageSize = pageSize;
_documentStore = documentStore.Initialize();
}
public void Run(string databasName)
{
var pageIndex = 0;
while (true)
{
using (var session = _documentStore.OpenSession(databasName))
{
var ravenJObjects = session.Query<RavenJObject>().Skip(_pageSize * pageIndex).Take(_pageSize);
if (!ravenJObjects.Any()) break;
foreach (var ravenJObject in ravenJObjects)
{
var ravenJTokenActionType = ravenJObject.SelectToken("ActionType");
if (ravenJTokenActionType == null || ravenJTokenActionType.Type != JTokenType.String) continue;
var actionType = ravenJTokenActionType.ToString();
var actionTypes = new List<string> { actionType };
ravenJObject["ActionType"] = new RavenJArray(actionTypes);
//// In case you want to rename property
//ravenJObject["ActionTypes"] = new RavenJArray(actionTypes);
//ravenJObject.Remove("ActionType");
}
session.SaveChanges();
}
pageIndex++;
}
}
}
}
我有一个名为 Actions 的文档集合。数据库中的操作如下所示:
{
"Name": "Name1",
"ActionType": "typeA"
}
我需要迁移所有 Action,这样 ActionType 属性 就会包含一个字符串数组:
{
"Name": "Name1",
"ActionType": ["typeA"]
}
我不想像提到的那样在我的项目中创建任何转换器 here。 那应该是一个简单的实用程序,可以单独运行。
想法是加载所有文档,进行必要的更改并保存它们(如 here)。我当前的代码看起来像这样,但它不能正常工作:
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Raven.Client;
using Raven.Client.Document;
using Raven.Client.Linq;
using Raven.Json.Linq;
namespace RavenDbMigration
{
public class SimpleMigrator
{
private readonly IDocumentStore _documentStore;
public SimpleMigrator(IDocumentStore documentStore)
{
_documentStore = documentStore;
}
public void Run()
{
using (IDocumentSession session = _documentStore.OpenSession())
{
var fullRavenIdsList = new List<string> {"1", "2", "3"};
RavenJObject[] ravenJObjects = session.Load<RavenJObject>(fullRavenIdsList); // Problem here - ravenJObjects contains 3 null values instead of actions
foreach (var ravenJObject in ravenJObjects)
{
var results = ravenJObject["Actions"] as RavenJArray;
if (results != null)
{
foreach (var result in results)
{
if (result != null && result.ContainsKey("ActionType"))
{
var actionTypes = new List<string>();
var actionType = result.Value<string>("ActionType");
if (actionType != null)
{
actionTypes.Add(actionType);
}
result["ActionType"] = new RavenJArray(actionTypes);
}
}
}
}
session.SaveChanges();
}
}
}
}
我使用 RavenDB.Client 版本 2.5.2700。
您需要创建一个类型为 List 的新字段,然后将数据迁移到列表中,而且您没有分页,因此您需要分页以获取所有数据才能为所有记录工作。
之后,您从模型中删除旧的单个字符串 属性,然后当您的数据进行更多更新等时,这个 属性 将被删除。
或
你按照他们告诉你的方式去做,在 link 提供的情况下,创建那个 post 的人拥有 RavenDB 并且知道他在说什么,如果他说这是最好的方法,你通常可以保证它是。
您可以通过 Raven Studio 或代码修补文档集 "Actions"。
this.ActionType = [this.ActionType];
这将导致文档如下所示:
"Name": "Name1",
"ActionType": [
"typeA"
]
如果有人对如何从代码执行此迁移感兴趣,请查看示例代码:
using System.Collections.Generic;
using System.Linq;
using Raven.Client;
using Raven.Client.Linq;
using Raven.Imports.Newtonsoft.Json.Linq;
using Raven.Json.Linq;
namespace RavenDbMigration
{
public class SimpleMigrator
{
private readonly IDocumentStore _documentStore;
private readonly int _pageSize;
public SimpleMigrator(IDocumentStore documentStore, int pageSize = 128)
{
_pageSize = pageSize;
_documentStore = documentStore.Initialize();
}
public void Run(string databasName)
{
var pageIndex = 0;
while (true)
{
using (var session = _documentStore.OpenSession(databasName))
{
var ravenJObjects = session.Query<RavenJObject>().Skip(_pageSize * pageIndex).Take(_pageSize);
if (!ravenJObjects.Any()) break;
foreach (var ravenJObject in ravenJObjects)
{
var ravenJTokenActionType = ravenJObject.SelectToken("ActionType");
if (ravenJTokenActionType == null || ravenJTokenActionType.Type != JTokenType.String) continue;
var actionType = ravenJTokenActionType.ToString();
var actionTypes = new List<string> { actionType };
ravenJObject["ActionType"] = new RavenJArray(actionTypes);
//// In case you want to rename property
//ravenJObject["ActionTypes"] = new RavenJArray(actionTypes);
//ravenJObject.Remove("ActionType");
}
session.SaveChanges();
}
pageIndex++;
}
}
}
}