将SQL表转换为mongoDB文档

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

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

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

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

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

(请注意,这来自mongo fanboi)

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

static void Main(string[] args) { List tablelist = new List(); 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 coll = db.GetCollection("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 collection = db.GetCollection(table); collection.Drop(); } conn.Open(); SqlDataReader reader = cmd.ExecuteReader(); List bsonlist = new List(1000); while (reader.Read()) { if (i == 1000) { using (server.RequestStart(db)) { //MongoCollection coll = db.GetCollection(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 coll = db.GetCollection(table); coll.InsertBatch(bsonlist); bsonlist.RemoveRange(0, bsonlist.Count); } i = 0; } } } } } 

我必须创建这样做的工具。 它使用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(),out d)) { co[prop.Name] = d; } //c.Value().Dump(); //c.Value().Dump(); //co[c.Name] } //co["APT_Latitude"].Value().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> 1

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

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

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

Norm和samus c#mongo驱动程序都支持强类型类作为文档传递。 意味着它像Nhiberbate和LINQ to SQL一样酷。

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

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