gpt4 book ai didi

c# - 使用并行写入 MongoDB 时出错

转载 作者:可可西里 更新时间:2023-11-01 09:14:20 30 4
gpt4 key购买 nike

我在 mongo 中有一个包含子文档的集合,然后读取 xml 文件,它们将记录在 MongoDB 中。每个 xml 文件都是 mongo 中的一个文档。

我的类(class)

public class Header
{
public Header()
{
Operation= new List<Operation>();
}

public ObjectId Id { get; set; }
public Int64 Code1 {get; set;}
public Int64 Code2 {get; set;}
public string Name { get; set; }
public List<Operation> Operations { get; set; }
}

public class Operation
{
public Operation()
{
Itens = new List<Item>();
}

public string Value { get; set; }
public List<Item> Item { get; set; }
}

public class Item
{
public string Value { get; set; }
}

类中的Headline,以及Codigo2 Code1用于在MongoDB中创建文档的索引。 Code1 和 Codigo2 组成 XML 文件名,因为它们都在一个文件夹中,所以不可能重复。

在 MongoDB 中记录

要在 mongo 中记录,请使用以下代码:

var po = new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount > 1 ? Environment.ProcessorCount / 2 : 1 };

Parallel.ForEach(arquivos, po, (arquivo, state) =>
{

MongoCollection<Header> collection = MongoConnect.GetHeader();

try
{
var Header = new Header();
Header.Name = @"Valor 1";
Header.Code1 = arquivo.Name.Split('-').Count() > 1 ? Int64.Parse((arquivo.Name.Split('-')[1]).Replace(".", "")) : 0;
Header.Code2 = arquivo.Name.Split('-').Count() > 1 ? Int64.Parse((arquivo.Name.Split('-')[2]).Replace(".siag", "")) : 0;

var body = record.SelectSingleNode("body");
if (body != null)
{
string[] linhas = body.InnerText.Split(new String[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
foreach (var linha in linhas)
{
string conteudo = linha;
var operation = new Operation();
if (!conteudo.Contains("\t"))
{
string tipo = conteudo.Substring(0, conteudo.IndexOf(' ')).Trim();
string tabela = conteudo.Substring(0, conteudo.IndexOf("Quando:", System.StringComparison.Ordinal)).Trim();
operation.value = tabela;
conteudo = conteudo.Remove(0, (tabela + " Quando:").Length);

Header.Operations.Add(operation);
}
else
{
var item = new Item();
string[] campos = conteudo.Split('\t');
item.Value = campos[0];

Header.Operations.Last().Itens.Add(item);
}
}

try
{
collection.Save(Header);
}
catch (Exception ex)
{
//Duplicate Key error show here
}
}
}
catch (Exception ex)
{
//Log Error Here
}

});

注意:请不要考虑阅读文件,放在那里只是为了说明。

完全错误

Erro: WriteConcern detected an error ''. (Response was { "ok" : 1, "code" : 11000, "err" :
"insertDocument :: caused by :: 11000 E11000 duplicate key error index:
DB.Collection.$Codigo1_1_Codigo2_1 dup key: { : 359922397, : 1217185957 }",
"n" : NumberLong(0) })

最佳答案

原因是这样的:source code

显示创建的 objectId :

static ObjectId()
{
__staticMachine = (GetMachineHash() + AppDomain.CurrentDomain.Id) & 0x00ffffff; // add AppDomain Id to ensure uniqueness across AppDomains
__staticIncrement = (new Random()).Next();

try
{
__staticPid = (short)GetCurrentProcessId(); // use low order two bytes only
}
catch (SecurityException)
{
__staticPid = 0;
}
}

但是如果你运行:

  var po = new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount > 1 ? Environment.ProcessorCount / 2 : 1 };

var items = new List<string>()
{
"Foo",
"Bar"
};
Parallel.ForEach(items, po, (arquivo, state) =>
{
Console.WriteLine((new Random()).Next());
});

你得到:

  1259271181
1259271181

因为随机并没有很好地并行化。您必须定义一个不使用 ObjectId 的 Id。或者制作 threadsafe

根据我们的评论,我会创建像这样的标题类:

public class Header
{
public Header()
{
Operation= new List<Operation>();
}
[BsonId]
public Codes Id {get; set;}
public Int64 Code2 {get; set;}
public string Name { get; set; }
public List<Operation> Operations { get; set; }
}
public class Codes {
public Int64 Code1 {get; set;}
public Int64 Code2 {get; set;}
}

关于c# - 使用并行写入 MongoDB 时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25664739/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com