【问题标题】:Deserialize json generated by mongodb that contains bson datatypes反序列化由 mongodb 生成的包含 bson 数据类型的 json
【发布时间】:2016-08-11 17:26:33
【问题描述】:

我收到了一些 JSON 数据文件——但是,每个对象中都包含 BSON 数据类型;最重要的是,它是一个非常大的 tojson 转储(数百万条记录)。

我正在尝试反序列化数据,但正如预期的那样失败了。

JSON 文件包含以下内容:

"someKey" : NumberLong("1234567889"),

里面也有 ISODate...

有没有办法用 Json.net 来处理这个问题?似乎可能有一些设置让它使用自定义函数而不是特定键的内置解析器?

*已更新以包含用于非常大(100GB+ 文件)的流+文本阅读器的代码

using (StreamReader file = File.OpenText(@"\\largedump.txt"))
            using (JsonTextReader reader = new JsonTextReader(file))
            {
                reader.SupportMultipleContent = true;    
                var serializer = new JsonSerializer();
                while (reader.Read())
                {
                    if (reader.TokenType == JsonToken.StartObject)
                    {
                        Contacts c = serializer.Deserialize<Contacts>(reader);
                        Console.WriteLine(c.orgId);
                    }
                }
            }

【问题讨论】:

  • {"someKey" : NumberLong("1234567889")} 不是有效的 JSON。请参阅JSON Standard。话虽如此,Json.NET 支持标准的一些扩展,包括constructors。如果您可以将 JSON 预处理为 {"someKey" : new NumberLong("1234567889")},则可以使用 Json.NET 解析它
  • 是的 - 它无效,因为 DBA 没有严格转储它;这会更好,因为它会用'$numberlong'在json中表示它,我已经编码了......现在必须调整。似乎 id 必须从阅读器中捕获字符串以对其进行预处理...
  • 我认为您可能需要使用某种正则表达式在 NumberLong 之前插入 new(或完全删除它),将结果流式传输到临时文件。
  • 你会说:要么插入新的...或者只是删除 NumberLong(" 及其结尾 ")... 会产生相同的结果吗? :)
  • 似乎没有一种足够简单的方法将流转储到文件,因为您必须依靠 jsontextreader 来查找集合对象的结尾 - 由于 json 无效,它本身会引发错误....我最终只是预流了整个文件并清除了垃圾...

标签: c# json mongodb serialization bson


【解决方案1】:

你可以使用mongo驱动bson序列化器:

使用 MongoDB.Bson.Serialization;

  var bjson = @"{
                        '_id' : ObjectId('57ac672e34780e59784d7d2a'),
                        'ActivePick' : null,
                        'EventCodeId' : null,
                        'Frame' : { '$binary' : 'AgY=', '$type' : '00' },
                        'FrameTimeStamp' : ISODate('2016-08-11T11:53:18.541Z'),
                        'ServerUserId' : 0,
                        'ServerUserName' : null,
                        'SesionId' : 0,
                        'TraderId' : null,
                        'TraderName' : null
                    }";

        var bsonDocument = BsonDocument.Parse(bjson);
        var myObj = BsonSerializer.Deserialize<FrameDocument>(bsonDocument);

来源here

编辑

我对给定的方法没有任何问题。请参阅 github 解决方案,因为它正在序列化没有问题。

            string line;
            using (TextReader file = File.OpenText("ImportDataFromBJsonFile\\a.json"))
            {
                while ((line = file.ReadLine()) != null)
                {
                    var bsonDocument = BsonDocument.Parse(line);
                    var myObj = BsonSerializer.Deserialize<Zxed>(bsonDocument);
                }
            }

source(sln project)

【讨论】:

  • 因为我们需要在输入上有一个字符串 - 这是由 streamRedar 提供的 - 那么我在这里看不到任何问题。
  • 我不认为它这么简单 - 32 GB 导出文件; 100,000,000 条记录;您不能使用简单的流式阅读器,它需要是 jsontextreader 以便它可以找到每个 json 令牌(记录)的开始和结束。如果您知道 jsontextreader 的替代方法可以做到这一点,您能否更新您的解决方案?
  • @zxed 你能检查我的编辑并发布你的数据样本吗?
  • 是不是假设每条json记录都是每行?
  • 数据不是每行 1 个 - 如果是,这将不是问题,因为我们不需要 jsontextreader :) 出于某种原因, printjson 是使用 printjson 而不是 printjsononeline 执行的跨度>
猜你喜欢
  • 2011-09-02
  • 1970-01-01
  • 1970-01-01
  • 2017-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-16
  • 1970-01-01
相关资源
最近更新 更多