U-SQL 自定义行分隔符上的自定义提取器和 json
U-SQL custom extractor on custom row delimiter and json
我有几个具有以下数据结构的文本文件:
{
huge
json
block that spans across multiple lines
}
--#newjson#--
{
huge
json
block that spans across multiple lines
}
--#newjson#--
{
huge
json
block that spans across multiple lines
} etc....
所以实际上 json 个块 行分隔 由 "--##newjson##--"
字符串。
我正在尝试编写一个客户提取器来解析它。问题是我不能使用 string
数据类型来提供 json 反序列化器,因为它的最大大小为 128 KB,而 json 块不适合这个。使用自定义提取器解析此文件的最佳方法是什么?
我试过使用下面的代码,但它不起作用。甚至行分隔符 "--#newjson#--"
似乎也无法正常工作。
public SampleExtractor(Encoding encoding, string row_delim = "--#newjson#--", char col_delim = ';')
{
this._encoding = ((encoding == null) ? Encoding.UTF8 : encoding);
this._row_delim = this._encoding.GetBytes(row_delim);
this._col_delim = col_delim;
}
public override IEnumerable<IRow> Extract(IUnstructuredReader input, IUpdatableRow output)
{
//Read the input by json
foreach (Stream current in input.Split(_encoding.GetBytes("--#newjson#--")))
{
var serializer = new JsonSerializer();
using (var sr = new StreamReader(current))
using (var jsonTextReader = new JsonTextReader(sr))
{
var jsonrow = serializer.Deserialize<JsonRow>(jsonTextReader);
output.Set(0, jsonrow.status.timestamp);
}
yield return output.AsReadOnly();
}
}
解决方法如下:
1) 创建一个与您的 JSON 对象等效的 C#
注意:- 假设您的所有 json 对象在您的文本文件中都是相同的。
例如:
Json代码
{
"id": 1,
"value": "hello",
"another_value": "world",
"value_obj": {
"name": "obj1"
},
"value_list": [
1,
2,
3
]
}
C# 等价物
public class ValueObj
{
public string name { get; set; }
}
public class RootObject
{
public int id { get; set; }
public string value { get; set; }
public string another_value { get; set; }
public ValueObj value_obj { get; set; }
public List<int> value_list { get; set; }
}
2) 根据定界符完成拆分后,如下更改反序列化代码
using (JsonReader reader = new JsonTextReader(sr))
{
while (!sr.EndOfStream)
{
o = serializer.Deserialize<List<MyObject>>(reader);
}
}
这将反序列化 c# class 对象中的 json 数据,这将解决您的目的。
稍后您可以再次序列化或以文本或...任何文件打印。
希望对您有所帮助。
您不需要自定义提取器来执行此操作。
最佳解决方案是逐行添加一个 json。然后您可以使用文本提取器逐行提取。您也可以选择自己的分隔符。
REFERENCE ASSEMBLY [Newtonsoft.Json];
REFERENCE ASSEMBLY [Microsoft.Analytics.Samples.Formats];
@JsonLines=
EXTRACT
[JsonLine] string
FROM
@Full_Path
USING
Extractors.Text(delimiter:'\b', quoting : false);
@ParsedJSONLines =
SELECT
Microsoft.Analytics.Samples.Formats.Json.JsonFunctions.JsonTuple([JsonLine]) AS JSONLine
FROM
@JsonLines
@AccessToProperties=
SELECT
JSONLine["Property"] AS Property
FROM
@ParsedJSONLines;
我有几个具有以下数据结构的文本文件:
{
huge
json
block that spans across multiple lines
}
--#newjson#--
{
huge
json
block that spans across multiple lines
}
--#newjson#--
{
huge
json
block that spans across multiple lines
} etc....
所以实际上 json 个块 行分隔 由 "--##newjson##--"
字符串。
我正在尝试编写一个客户提取器来解析它。问题是我不能使用 string
数据类型来提供 json 反序列化器,因为它的最大大小为 128 KB,而 json 块不适合这个。使用自定义提取器解析此文件的最佳方法是什么?
我试过使用下面的代码,但它不起作用。甚至行分隔符 "--#newjson#--"
似乎也无法正常工作。
public SampleExtractor(Encoding encoding, string row_delim = "--#newjson#--", char col_delim = ';')
{
this._encoding = ((encoding == null) ? Encoding.UTF8 : encoding);
this._row_delim = this._encoding.GetBytes(row_delim);
this._col_delim = col_delim;
}
public override IEnumerable<IRow> Extract(IUnstructuredReader input, IUpdatableRow output)
{
//Read the input by json
foreach (Stream current in input.Split(_encoding.GetBytes("--#newjson#--")))
{
var serializer = new JsonSerializer();
using (var sr = new StreamReader(current))
using (var jsonTextReader = new JsonTextReader(sr))
{
var jsonrow = serializer.Deserialize<JsonRow>(jsonTextReader);
output.Set(0, jsonrow.status.timestamp);
}
yield return output.AsReadOnly();
}
}
解决方法如下:
1) 创建一个与您的 JSON 对象等效的 C# 注意:- 假设您的所有 json 对象在您的文本文件中都是相同的。 例如:
Json代码
{
"id": 1,
"value": "hello",
"another_value": "world",
"value_obj": {
"name": "obj1"
},
"value_list": [
1,
2,
3
]
}
C# 等价物
public class ValueObj
{
public string name { get; set; }
}
public class RootObject
{
public int id { get; set; }
public string value { get; set; }
public string another_value { get; set; }
public ValueObj value_obj { get; set; }
public List<int> value_list { get; set; }
}
2) 根据定界符完成拆分后,如下更改反序列化代码
using (JsonReader reader = new JsonTextReader(sr))
{
while (!sr.EndOfStream)
{
o = serializer.Deserialize<List<MyObject>>(reader);
}
}
这将反序列化 c# class 对象中的 json 数据,这将解决您的目的。 稍后您可以再次序列化或以文本或...任何文件打印。
希望对您有所帮助。
您不需要自定义提取器来执行此操作。
最佳解决方案是逐行添加一个 json。然后您可以使用文本提取器逐行提取。您也可以选择自己的分隔符。
REFERENCE ASSEMBLY [Newtonsoft.Json];
REFERENCE ASSEMBLY [Microsoft.Analytics.Samples.Formats];
@JsonLines=
EXTRACT
[JsonLine] string
FROM
@Full_Path
USING
Extractors.Text(delimiter:'\b', quoting : false);
@ParsedJSONLines =
SELECT
Microsoft.Analytics.Samples.Formats.Json.JsonFunctions.JsonTuple([JsonLine]) AS JSONLine
FROM
@JsonLines
@AccessToProperties=
SELECT
JSONLine["Property"] AS Property
FROM
@ParsedJSONLines;