我有2GB文件(其中9个),其中包含大约12M个字符串记录,我想将每个文件作为文档插入本地mongodb(windows)。
现在我逐行阅读并插入每一行(第一行是不必要的标题),如下所示:
bool readingFlag = false;
foreach (var line in File.ReadLines(file))
{
if (readingflag)
{
String document = "{'read':'" + line + "'}";
var documnt = new BsonDocument(
MongoDB
.Bson
.Serialization
.BsonSerializer
.Deserialize<BsonDocument>(document));
await collection.InsertOneAsync(documnt);
readingflag = false;
}
else
{
readingflag = true;
}
}
这种方法有效但不如我预期的那么快。我现在位于文件的中间,我认为只需一个文件就可以在大约4个小时内结束。 (所有数据都是40小时)
我认为我的瓶颈是文件读取,但因为它是一个非常大的文件VS不会让我把它加载到内存中(内存异常)。
我有没有其他方式在这里失踪?
答案 0 :(得分:1)
我认为我们可以利用这些东西:
TextData
将序列化推送到其他线程您可以立即玩限制 - 因为这取决于从文件中读取的数据量
public class TextData{
public ObjectId _id {
get;
set;
}
public string read {
get;
set;
}
}
public class Processor{
public async void ProcessData() {
var client = new MongoClient("mongodb://localhost:27017");
var database = client.GetDatabase("test");
var collection = database.GetCollection < TextData > ("Yogevnn");
var readingflag = false;
var listOfDocument = new List < TextData > ();
var limiAtOnce = 100;
var current = 0;
foreach(var line in File.ReadLines( @ "E:\file.txt")) {
if (readingflag) {
var dataToInsert = new TextData {
read = line
};
listOfDocument.Add(dataToInsert);
readingflag = false;
Console.WriteLine($ "Current position: {current}");
if (++current == limiAtOnce) {
current = 0;
Console.WriteLine($ "Inserting data");
var listToInsert = listOfDocument;
var t = new Task(() = > {
Console.WriteLine($ "Inserting data START");
collection.InsertManyAsync(listToInsert);
Console.WriteLine($ "Inserting data FINISH");
});
t.Start();
listOfDocument = new List < TextData > ();
}
} else {
readingflag = true;
}
}
// insert remainder
await collection.InsertManyAsync(listOfDocument);
}
}
欢迎任何评论!
答案 1 :(得分:0)
在我的实验中,我发现Parallel.ForEach(File.ReadLines("path"))
是最快的。
文件大小约为42 GB。我也试过批处理一组100行并保存批处理但比Parallel.ForEach
慢。