C# 从MongoDB导入数据到mysql
来源:互联网 发布:树人围棋软件注册码 编辑:程序博客网 时间:2024/05/20 06:09
因为项目需要,经常导入MongoDB数据到Mysql,故而做了一个小工具来进行数据迁移。
在这个过程中,因为效率问题,探索了很多方法,单条遍历拼接插入命令、使用事务进行处理(也是拼接插入命令)、使用MySqlBulkLoad批量导入数据到mysql。
下边分别描述一下三种处理方法:
a.从MongoDB中获取指定的collection
#region 从MongoDB中获取数据 string connetMongoDB = "mongodb://" + MongoDBIP.Text; var Client = new MongoClient(connetMongoDB); _message.messageA += "MongDB 连接成功\n"; var DataBase = Client.GetDatabase(MongoDBDataBaseName.Text); var DataCollection = DataBase.GetCollection<BsonDocument>(MongoDBTableName.Text); var documents = DataCollection.Find(new BsonDocument()).Limit(100).ToListAsync().Result; #endregion
b.从collection中获取数据表的列信息
foreach (BsonDocument bs in documents) { var obj = bs.ToDictionary(); if (tableColloumns.Count < obj.Keys.Count) { int i = 0; foreach (var key in obj.Keys) { string hearder = key.ToString(); if (CheckHeader(tableColloumns, hearder)) { tableColloumns.Insert(i, RemoveSpecialLetter(hearder)); i++; } } } }
c.创建Mysql数据库
private void CreatMysqlDB() { string connectMysql = "server = " + MysqlIP.Text + "; database =" + "; user id = " + MysqlUserName.Text + "; password = " + MysqlPassword.Text + ";pooling=true;CharSet=utf8;port=3306"; MySqlConnection conn = new MySqlConnection(connectMysql); conn.Open(); string creatMysqlDB = "CREATE DATABASE " + MysqlDatabase.Text + ";"; MySqlCommand cmd = new MySqlCommand(creatMysqlDB, conn); _message.messageA += "连接Mysql成功···\n"; try { cmd.ExecuteNonQuery(); _message.messageA += "创建Mysql数据库成功···\n"; } catch (Exception e) { MessageBox.Show(e.Message); } }d.创建mysql数据库表
using (var Conn = new MySqlConnection(connectMysql)) { Conn.Open(); _message.messageA += "连接Mysql成功···\n"; #region 创建数据库表 string createStatement = "CREATE TABLE " + MysqlTable.Text + " ("; int i = 0; var IsRegex = new Regex("^Is[A-Z]"); foreach (string colloumn in tableColloumns) {//增加数据库表列的属性设置 if (i == 0) { createStatement += colloumn + " VarChar(255) not null primary key,"; i++; } else if (IsRegex.Match(colloumn).Success) { createStatement += colloumn + " tinyint(4),"; i++; } else if (colloumn == "Html") { createStatement += colloumn + " longtext,"; i++; } else if (colloumn == "Content") { createStatement += colloumn + " longtext,"; i++; } else if (colloumn == "ContentHtml") { createStatement += colloumn + " longtext,"; i++; } else { createStatement += " " + colloumn + " text,"; i++; } } createStatement = createStatement.Remove(createStatement.Length - 1); createStatement += ") ENGINE=MyISAM DEFAULT CHARSET=utf8";//表设置 using (MySqlCommand cmd = new MySqlCommand(createStatement, Conn)) { try { cmd.ExecuteNonQuery(); _message.messageA += "创建Mysql表成功···\n"; } catch (Exception ex) { MessageBox.Show(ex.Message); } } #endregion}e.开始写入数据
方法1.遍历collection,拼接插入命令(单条执行)
public class ItemClass { public List<string> values = new List<string>(); }
public List<string> ChangeToStrlist(Dictionary<string, object>.KeyCollection list) { List<string> listStr = new List<string>(); foreach (var item in list) listStr.Add(RemoveSpecialLetter(item.ToString())); return listStr; } public static List<string> ChangeToStrlist(Dictionary<string, object>.ValueCollection list) { List<string> listStr = new List<string>(); foreach (var item in list) listStr.Add(item.ToString()); return listStr; }
#region 单条处理数据 string strsql = GetCommand(); int count = 0; await DataCollection.Find(new BsonDocument()).ForEachAsync(bs => { using (var Conn2 = new MySqlConnection(connectMysql)) { Conn2.Open(); MySqlCommand cmd = new MySqlCommand(); cmd.Connection = Conn2; cmd.CommandText = strsql; cmd.Parameters.Clear(); ItemClass item = new ItemClass(); var obj = bs.ToDictionary(); var keys = ChangeToStrlist(obj.Keys); var values = ChangeToStrlist(obj.Values); int temp = 0; foreach (var colloumn in tableColloumns) { if (colloumn == keys[temp]) { item.values.Add(values[temp]); temp++; } else { item.values.Add(string.Empty); } } temp = 0; foreach (string colloumn in tableColloumns) { cmd.Parameters.AddWithValue(colloumn, item.values[temp]); temp++; } try { cmd.ExecuteNonQuery(); ncount++; } catch (Exception EX) { MessageBox.Show(EX.Message); } if (ncount% 10000 == 0) { _message.messageA += "已写入" + ncount.ToString() + "条数据\n"; } } } ); _message.messageA += "已写入" + ncount.ToString() + "条数据\n"; _message.messageA += "向Mysql表写入数据完成\n";#endregion
方法2:使用事务处理
#region 使用事务处理,一次处理500条数据(有一个问题,当mongdb数据量很大的时候,会内存崩溃,这个问题可以采用分段获取的方式解决,请自行解决) int count = 500; List<ItemClass> items = new List<ItemClass>(); foreach (BsonDocument bs in DataCollection.Find(new BsonDocument()).ToListAsync().Result) { if (count < 500) { var obj = bs.ToDictionary(); ItemClass item = new ItemClass(); var keys = ChangeToStrlist(obj.Keys); var values = ChangeToStrlist(obj.Values); int temp = 0; foreach (var colloumn in tableColloumns) { if (colloumn == keys[temp]) { item.values.Add(values[temp]); temp++; } else { item.values.Add(string.Empty); } } items.Add(item); count++; } else { ExecuteSqlTran(items); ncount += count; _message.messageA += "已写入" + ncount.ToString() + "条数据\n"; items.Clear(); count = 0; } } ExecuteSqlTran(items); ncount += count; items.Clear(); _message.messageA += "已写入" + ncount.ToString() + "条数据\n"; _message.messageA += "向Mysql表写入数据完成\n"; #endregion
public void ExecuteSqlTran(List<ItemClass> items) { string connectMysql2 = "server = " + MysqlIP.Text + "; database =" + MysqlDatabase.Text + "; user id = " + MysqlUserName.Text + "; password = " + MysqlPassword.Text + ";pooling=true;CharSet=utf8;port=3306"; using (MySqlConnection conn = new MySqlConnection(connectMysql2)) { conn.Open(); MySqlCommand cmd = new MySqlCommand(); cmd.Connection = conn; MySqlTransaction tx = conn.BeginTransaction(); cmd.Transaction = tx; string strsql = GetCommand(); try { for (int n = 0; n < items.Count; n++) { cmd.CommandText = strsql; cmd.Parameters.Clear(); var item = items[n]; int i = 0; foreach (string colloumn in tableColloumns) { cmd.Parameters.AddWithValue(colloumn, item.values[i]); i++; } cmd.ExecuteNonQuery(); if (n > 0 && (n % 500 == 0 || n == items.Count - 1)) { tx.Commit(); counts += items.Count; Console.WriteLine("写入" + counts + "条数据成功"); tx = conn.BeginTransaction(); } } } catch (System.Data.SqlClient.SqlException E) { Console.WriteLine("写入数据失败,回滚"); Console.ReadLine(); tx.Rollback(); MessageBox.Show(E.Message); //throw new Exception(E.Message); } } }
private string GetCommand() { // string cmdstr = "update WIRELESS_PERSON_T set PersonName=@PersonName, PersonSex='" + person.getPersonSex() + "', YID=@YID, caseinfoid='" + person.getCaseinfoid() + "', Kind='" + person.getKind()+ "', caseremark=@Caseremark, ArrivalKind='" + person.getArrivalKind() + "' where PersonId=" + person.getPersonId(); string command = @"insert into `" + MongoDBTableName.Text + "` ("; for (int k = 0; k < tableColloumns.Count; k++) { if (k == tableColloumns.Count - 1) command += "`" + tableColloumns[k] + "`)"; else command += "`" + tableColloumns[k] + "`,"; } command += "values( "; for (int j = 0; j < tableColloumns.Count; j++) { if (j == tableColloumns.Count - 1) command += "?" + tableColloumns[j] + ")"; else command += "?" + tableColloumns[j] + ","; } return command; }
3.使用MysqlBulkLoad进行数据迁移
#region 批处理处理数据 var Filter = Builders<BsonDocument>.Filter; var Cursor = DataCollection.Find(Filter.Empty).ToCursor(); var FileName = "temp.txt"; using (StreamWriter Writer = new StreamWriter(FileName, false, Encoding.UTF8)) { while (await Cursor.MoveNextAsync()) { foreach (var Document in Cursor.Current) { Writer.Write("<%RS%>"); foreach (var col in tableColloumns) { if (IsRegex.Match(col).Success) { Writer.Write($"{Document.GetValue(col, false).AsBoolean:1?0}<%COL%>"); } else if (col == "_id") { Writer.Write($"{Document.GetValue(col).AsObjectId.ToString()}<%COL%>"); } else { Writer.Write($"{Document.GetValue(col, string.Empty).AsString}<%COL%>"); } } Writer.Write("<%RE%>"); } } } var Bulk = new MySqlBulkLoader(Conn); Bulk.TableName = MysqlTable.Text; Bulk.ConflictOption = MySqlBulkLoaderConflictOption.Ignore; Bulk.Local = true; Bulk.Timeout =10* 60 * 1000; Bulk.CharacterSet = "utf8mb4"; Bulk.LinePrefix = "<%RS%>"; Bulk.LineTerminator = "<%RE%>"; Bulk.FieldTerminator = "<%COL%>"; Bulk.EscapeCharacter = '\b'; Bulk.FileName = FileName; ncount = Bulk.Load();#endregion _message.messageA += "已写入" + ncount.ToString() + "条数据\n"; _message.messageA += "向Mysql表写入数据完成\n";
以上就是三种解决办法,是从最笨的方法慢慢提高效率,所以推荐使用第三种方法。
阅读全文
0 0
- C# 从MongoDB导入数据到mysql
- 将数据从MongoDB导入到MySQL
- 将数据从MongoDB导入到MySQL
- 从mysql导入数据到mongodb
- 从mysql导入数据到mongodb的方法
- 从mysql数据库导入数据到mongodb的方法大全
- spark从mongodb导入数据到hive
- 从MongoDB抽取数据导入mysql
- 批量数据从excel导入到mysql
- 从文件导入数据到MySQL数据库
- Sqoop 数据从HDFS导入到mysql
- scoop导入数据从mysql到hive
- 从MySQL导入数据到ElastICsearch
- SQOOP从MySQL导入数据到HDFS
- SQOOP从MySQL导入数据到Hive
- 从MySQL到MongoDB(添加MongoDB循环插入数据方法)
- NavicatforMySQL 数据导入从excel导入数据到mysql
- 一个实现数据批量从mongodb导入Mysql的方案
- ionic启动页面黑屏不显示的问题的解决
- shiro 单点登录
- 字符编码:Unicode和UTF-8之间的关系
- 找不到引用?! 找“NuGet程序包管理器”
- 用分治法解决循环赛日程表
- C# 从MongoDB导入数据到mysql
- 有关Caffe训练好的模型在Python接口下使用分类不准确的问题解决
- NOJ1571八数码问题
- 【1】用jsoup来实现简单的java爬虫
- 正则表达式的常用操作符
- 留给人类的时间不多了?现在不学机器学习更待何时!
- Android程序签名打包 什么是签名,有什么用:
- Bean named 'deptDao' must be of type [com.zttech.sys.dao.IGroupDao], but was actually of type [com.s
- AngularJS(1.X)