.net RavenDB迁移:将属性从字符串更新为字符串数组

.net RavenDB迁移:将属性从字符串更新为字符串数组,.net,ravendb,data-migration,.net,Ravendb,Data Migration,我有一个名为Actions的文档集合。db中的操作如下所示: { "Name": "Name1", "ActionType": "typeA" } "Name": "Name1", "ActionType": [ "typeA" ] 我需要迁移所有操作,以便ActionType属性包含字符串数组: { "Name": "Name1", "ActionType": ["typeA"] } 我不想像前面提到的那样在我的项目中创建任何转换器。 这应该是一个可以

我有一个名为Actions的文档集合。db中的操作如下所示:

{
    "Name": "Name1",
    "ActionType": "typeA"
}
"Name": "Name1",
"ActionType": [
  "typeA"
]
我需要迁移所有操作,以便ActionType属性包含字符串数组:

{
    "Name": "Name1",
    "ActionType": ["typeA"]
}
我不想像前面提到的那样在我的项目中创建任何转换器。 这应该是一个可以单独运行的简单实用程序

其思想是加载所有文档,进行必要的更改并保存它们(如)。我当前的代码看起来是这样的,但工作不正常:

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();
            }
        }    
    }
}
使用系统集合;
使用System.Collections.Generic;
使用System.Linq;
使用Raven.Client;
使用Raven.Client.Document;
使用Raven.Client.Linq;
使用Raven.Json.Linq;
名称空间RavenDbMigration
{
公共类单纯器
{
私有只读IDocumentStore\u documentStore;
公共文档管理器(IDocumentStore documentStore)
{
_documentStore=documentStore;
}
公开募捐
{
使用(IDocumentSession=\u documentStore.OpenSession())
{
var fullravenislist=新列表{“1”、“2”、“3”};
RavenJObject[]ravenJObjects=session.Load(FullRavenisList);//这里有问题-ravenJObjects包含3个空值,而不是操作
foreach(ravenjabjects中的var ravenjabobject)
{
var results=ravenJObject[“Actions”]作为RavenJArray;
如果(结果!=null)
{
foreach(结果中的var结果)
{
if(result!=null&&result.ContainsKey(“ActionType”))
{
var actionTypes=新列表();
var actionType=结果值(“actionType”);
if(actionType!=null)
{
actionType.Add(actionType);
}
结果[“ActionType”]=新数组(ActionType);
}
}
}
}
session.SaveChanges();
}
}    
}
}

我使用的是2.5.2700版的RavenDB.Client。

您需要创建一个具有列表类型的新字段,然后将数据迁移到列表中,而且您没有分页功能,因此您需要分页以获取所有数据,以使其适用于所有记录

之后,从模型中删除旧的单字符串属性,然后当数据进行任何更新等时,此属性将被删除


你按照他们告诉你的方式来做,在提供的链接上,创建该帖子的人拥有RavenDB,并且知道他在说什么,如果他说这是最好的方式,你通常可以保证是这样。

你可以通过Raven Studio或通过代码修补你的文档集“操作”

this.ActionType = [this.ActionType];
这将导致一个如下所示的文档:

{
    "Name": "Name1",
    "ActionType": "typeA"
}
"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++;
            }
        }
    }
}
使用System.Collections.Generic;
使用System.Linq;
使用Raven.Client;
使用Raven.Client.Linq;
使用Raven.Imports.Newtonsoft.Json.Linq;
使用Raven.Json.Linq;
名称空间RavenDbMigration
{
公共类单纯器
{
私有只读IDocumentStore\u documentStore;
私有只读int_pageSize;
公共SimpleStor(IDocumentStore documentStore,int pageSize=128)
{
_pageSize=页面大小;
_documentStore=documentStore.Initialize();
}
公共无效运行(字符串DatabaseName)
{
var pageIndex=0;
while(true)
{
使用(var会话=_documentStore.OpenSession(databasename))
{
var ravenjabjects=session.Query().Skip(_pageSize*pageIndex)。Take(_pageSize);
如果(!ravenjabjects.Any())中断;
foreach(ravenjabjects中的var ravenjabobject)
{
var ravenJTokenActionType=ravenJObject.SelectToken(“ActionType”);
如果(ravenJTokenActionType==null | | ravenJTokenActionType.Type!=JTokenType.String)继续;
var actionType=ravenJTokenActionType.ToString();
var actionTypes=新列表{actionType};
ravenJObject[“ActionType”]=新的RavenJArray(ActionType);
////如果您想重命名属性
//ravenJObject[“ActionTypes”]=新的RavenJArray(ActionTypes);
//删除(“ActionType”);
}
session.SaveChanges();
}
pageIndex++;
}
}
}
}

谢谢,这绝对是最简单的解决方案。