Пользовательский экстрактор U-SQL для пользовательского разделителя строк и json - PullRequest
0 голосов
/ 28 февраля 2019

У меня есть несколько текстовых файлов со следующей структурой данных:

{
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 КБ, и блоки 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();
    }
} 

Ответы [ 2 ]

0 голосов
/ 06 марта 2019

Вам не нужен специальный экстрактор для этого.

Лучшее решение - добавить один 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;
0 голосов
/ 04 марта 2019

Вот как вы можете найти решение:

1) Создать ac # эквивалент вашего JSON-объекта. Примечание: - Предполагая, что все ваши 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);
    }
}

Это десериализует данные json в объекте класса c #, что решит вашу задачу.Позже вы можете снова сериализовать или распечатать его в текстовом или ... любом файле.

Надеюсь, это поможет.

...