将SQL表转换为mongoDB文档

时间:2010-12-07 01:30:18

标签: c# sql mongodb

将一个SQL数据库(例如1个表)转换为mongoDB文档的最佳方法是什么?

我想我可以使用C#驱动程序并实现一个循环,它选择表中的每一行并将其保存在Mongo中。但是,我正在寻找一种更好的方法来转换大量数据..

5 个答案:

答案 0 :(得分:13)

这是我用于将数据从SQL服务器导入到我的盒子上的Mongodb的导入脚本。 此代码将在MongoDB中创建一个类似的表(存在于SQL DB中)。 您可以提供表格列表以导入为逗号分隔,并且所有这些表格都可以毫无问题地导入。

static void Main(string[] args)
{
    List<string> tablelist = new List<string>();
    if (!args[0].Contains(','))
        tablelist.Add(args[0]);
    else
        tablelist.AddRange(args[0].Split(','));
    string sqlconnectionstring = ConfigurationManager.ConnectionStrings["ConnectionString"].ToString();
    var connectionString = "mongodb://localhost/?safe=true;w=1;wtimeout=30s";
    var safemode = SafeMode.True;
    MongoServer server = MongoServer.Create(connectionString);
    MongoDatabase db = server.GetDatabase("testdb");
    MongoCollection<MongoDB.Bson.BsonDocument> coll = db.GetCollection<BsonDocument>("test");
    //coll.Find().Count();
    int i = 0;
    foreach (string table in tablelist)
    {

        using (SqlConnection conn = new SqlConnection(sqlconnectionstring))
        {
            string query = "select * from " + table;
            using (SqlCommand cmd = new SqlCommand(query, conn))
            {
                /// Delete the MongoDb Collection first to proceed with data insertion

                if (db.CollectionExists(table))
                {
                    MongoCollection<BsonDocument> collection = db.GetCollection<BsonDocument>(table);
                    collection.Drop();
                }
                conn.Open();
                SqlDataReader reader = cmd.ExecuteReader();
                List<BsonDocument> bsonlist = new List<BsonDocument>(1000);
                while (reader.Read())
                {
                    if (i == 1000)
                    {
                        using (server.RequestStart(db))
                        {
                            //MongoCollection<MongoDB.Bson.BsonDocument> 
                            coll = db.GetCollection<BsonDocument>(table);
                            coll.InsertBatch(bsonlist);
                            bsonlist.RemoveRange(0, bsonlist.Count);
                        }
                        i = 0;
                    }
                    ++i;
                    BsonDocument bson = new BsonDocument();
                    for (int j = 0; j < reader.FieldCount; j++)
                    {
                        if (reader[j].GetType() == typeof(String))
                            bson.Add(new BsonElement(reader.GetName(j), reader[j].ToString()));
                        else if ((reader[j].GetType() == typeof(Int32)))
                        {
                            bson.Add(new BsonElement(reader.GetName(j), BsonValue.Create(reader.GetInt32(j))));
                        }
                        else if (reader[j].GetType() == typeof(Int16))
                        {
                            bson.Add(new BsonElement(reader.GetName(j), BsonValue.Create(reader.GetInt16(j))));
                        }
                        else if (reader[j].GetType() == typeof(Int64))
                        {
                            bson.Add(new BsonElement(reader.GetName(j), BsonValue.Create(reader.GetInt64(j))));
                        }
                        else if (reader[j].GetType() == typeof(float))
                        {
                            bson.Add(new BsonElement(reader.GetName(j), BsonValue.Create(reader.GetFloat(j))));
                        }
                        else if (reader[j].GetType() == typeof(Double))
                        {
                            bson.Add(new BsonElement(reader.GetName(j), BsonValue.Create(reader.GetDouble(j))));
                        }
                        else if (reader[j].GetType() == typeof(DateTime))
                        {
                            bson.Add(new BsonElement(reader.GetName(j), BsonValue.Create(reader.GetDateTime(j))));
                        }
                        else if (reader[j].GetType() == typeof(Guid))
                            bson.Add(new BsonElement(reader.GetName(j), BsonValue.Create(reader.GetGuid(j))));
                        else if (reader[j].GetType() == typeof(Boolean))
                        {
                            bson.Add(new BsonElement(reader.GetName(j), BsonValue.Create(reader.GetBoolean(j))));
                        }
                        else if (reader[j].GetType() == typeof(DBNull))
                        {
                            bson.Add(new BsonElement(reader.GetName(j), BsonNull.Value));
                        }
                        else if (reader[j].GetType() == typeof(Byte))
                        {
                            bson.Add(new BsonElement(reader.GetName(j), BsonValue.Create(reader.GetByte(j))));
                        }
                        else if (reader[j].GetType() == typeof(Byte[]))
                        {
                            bson.Add(new BsonElement(reader.GetName(j), BsonValue.Create(reader[j] as Byte[])));
                        }
                        else
                            throw new Exception();
                    }
                    bsonlist.Add(bson);
                }
                if (i > 0)
                {
                    using (server.RequestStart(db))
                    {
                        //MongoCollection<MongoDB.Bson.BsonDocument> 
                        coll = db.GetCollection<BsonDocument>(table);
                        coll.InsertBatch(bsonlist);
                        bsonlist.RemoveRange(0, bsonlist.Count);
                    }
                    i = 0;
                }
            }
        }
    }
}

答案 1 :(得分:8)

FAR的驾驶方式最直接。导入/导出工具非常棒,但如果您将它们作为一对使用,则仅 。如果您的表包含日期并且您尝试从数据库导出并导入到mongo中,那么您就是疯狂的。

你也很幸运,在c#中。我们正在使用ruby,并且有一个3200万行的表,我们迁移到mongo。我们的最终解决方案是在postgres中创建一个疯狂的sql语句,输出json(包括一些非常复杂的东西以使日期正常运行)并将命令行上的查询输出传送到mongoimport。写作花了令人难以置信的令人沮丧的一天,并不是那种真正可以改变的东西。

因此,如果您可以使用它,请将ado.net与mongo驱动程序一起使用。如果没有,我祝你好: - )

(请注意,这是来自mongo fanboi)

答案 2 :(得分:1)

我必须创建这样做的工具。 它使用bcp.exe将数据导出到xml,然后使用Newtonsoft JSON.NET将其转换为json,然后使用mongoimport将其导入。花了不到一天,但不支持日期。

下面的一些代码(非常未清除:)

bcp.exe使用如下语法: bcp.exe“SELECT * from GeoData.dbo.Airports FOR XML RAW('Row'),ROOT('Root'),ELEMENTS”queryout D:\ TEMP \ tmp1045.tmp -Uxxxx -Pxxxx -Sxxxx -w -r“ “-q

JSON:

var r=XmlReader.Create("file://D:/1.xml");
    XmlDocument xdoc=new XmlDocument();
    xdoc.Load(r);
    string result="";





    //o["Root"]["Airport"];
    foreach(XmlNode n in xdoc.ChildNodes[0]){
        var rr= JsonConvert.SerializeXmlNode(n);    

        JObject o=JObject.Parse(rr);    

        var co=o.Children().Children().First();     

        foreach (JToken c in co.Children().Where(cc=>cc.Type==JTokenType.Property).ToList()){                   
            var prop=c as JProperty;            
            double d;
            if (double.TryParse(co[prop.Name].Value<string>(),out d))
            {
                co[prop.Name] = d;
            }           
            //c.Value<string>().Dump();
            //c.Value<string>().Dump();
            //co[c.Name]
        }

        //co["APT_Latitude"].Value<decimal>().Dump();       
        result=result + co.ToString(Newtonsoft.Json.Formatting.None)+"\r\n";


    }
    File.WriteAllText("D:/1.json",result);

    //result.Dump();

Mongoimport: D:\ MongoDB \ mongoimport.exe -c“test”-d“MongoStatic”1.json&gt; 1

答案 3 :(得分:1)

如果你喜欢玩Ruby,我会制作一个帮助你做到这一点的宝石:http://mongify.com/

可以找到源代码:https://github.com/anlek/mongify/

非常简单直接地定义您的架构以及它应该如何转换为mongodb。包括嵌入,重命名表,重命名字段和一堆其他选项。

答案 4 :(得分:0)

Norm&amp; samus c#mongo drivers支持强类型类作为文档传递。意味着它像Nhiberbate和LINQ to SQL一样酷。

我的想法是,您可以使用LINQ to SQL在c#(表示表的类)中创建实体以从sql server检索数据,并且可以使用相同的强类型类在mongo db中插入。

确保您的类在任何一个字段中都应具有 mongo标识符属性(在NoRM中)。这是为文档生成唯一ID。