|
Как оптимально парсить много больших XML файлов. | ☑ | ||
---|---|---|---|---|
0
LLIaMaH
27.12.19
✎
11:21
|
Есть файлы проверок прокуратуры, и 100 юрлиц с ИНН. Я читаю каждый файл кодом как внизу, обхожу все элементы, получаю от каждого ИНН юр лица которое проверяется, ищу ИНН в своем массиве ИНН, если нахожу то разбираю узел сохраняю данные, перехожу к следующему узлу.
ЧтениеXML = Новый ЧтениеXML; ЧтениеXML.ОткрытьФайл(Файл.ПолноеИмя); Фабрика = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML); Хотелось бы ускорить все это, думаю свои ИНН перенести в ТЗ и проиндексировать или упорядочить и применить двоичный поиск. А вот с ХМЛ мало опыта работы, можно ли как то ускорить чтение распознавание файла, к нему есть схема xsd, может както помочь? Можно ли искать по узлам ХМЛ нужные мне ИНН, может это будет быстрее чем обзод всего ХМЛ фала и сранение каждого узла с моим набором? |
|||
10
pechkin
27.12.19
✎
11:59
|
(9) если файлы большие, а ИНН где то вначале, то стоит юзать ЧтениеXML
|
|||
11
Кирпич
27.12.19
✎
12:41
|
да тупо загрузить и Найти()
|
|||
12
Кирпич
27.12.19
✎
12:42
|
а то щас начнется... технологии, xml, регламентные задания, потоки...
|
|||
13
Андроны едут
27.12.19
✎
12:45
|
(12) я бы добавил регулярные выражения и механизмы XDTO
|
|||
14
Кирпич
27.12.19
✎
12:47
|
(13) если бы в 1с были регулярки, то можно и регулярки. а так и Найти() хватит
|
|||
15
LLIaMaH
27.12.19
✎
12:55
|
(10) файлы большие, примерно 100 000 узлов, с сотней полей, каждый узел проверка прокуратуры, нужно читать каждый узел, в нем ИНН содержится, если ИНН "мой", я с узла читаю поля и пишу в базу, потом вывожу отчет по всем проверкам за год.
(11) Ваще я так и делаю, чтобы не доводить до парсинга, сначала ищу чтобы в файле был хотя бы один из моих ИНН, потмо парсю файл и читаю узлы. |
|||
16
lodger
27.12.19
✎
13:02
|
(15) а мог бы регуляркой выкусить
<начало узла> <...> <...> твой инн <...> <...> <...> <конец узла> и разбирать уже эти куски. текстом, или дописать теги начала и конца XML и юзать то же чтениеXML и даже старый код. |
|||
17
Garykom
гуру
27.12.19
✎
13:02
|
(0) Вместо того чтобы брать из XML по одному ИНН и искать среди своих 100, лучше ищи свои 100 сразу всему файлу XML
|
|||
18
H A D G E H O G s
27.12.19
✎
13:12
|
(0) Не используй ФабрикуXDTO, используй ЧтениеТекста
Проходи по тексту, находи тег, где ИНН хранится. Дальше вытаскивай ИНН и ищи в индексированной ТЗ. |
|||
19
Garykom
гуру
27.12.19
✎
13:22
|
Может сначала открыть XML как обычный текст и поискать там свои 100 ИНН ?
Если не нашли - и нахрен что то еще делать. |
|||
20
LLIaMaH
27.12.19
✎
13:46
|
(18) дак фабрика удобна, если мутить поиск по тексту это же стока гемора по поискам тегов...
|
|||
21
Вигор
27.12.19
✎
13:47
|
(20) Можно ПостроительDOM использовать.
|
|||
22
H A D G E H O G s
27.12.19
✎
13:51
|
(20) Тупо прочитать текст - быстрее, чем формировать из него xtdo структуру
|
|||
23
pechkin
27.12.19
✎
13:53
|
(18) тогда лучше grep какой юзать
|
|||
24
pechkin
27.12.19
✎
13:54
|
вот вариант.
файлы валятся в каталог. из каталога батником пеерносятся в нужный каталог только те, что имеют правильный инн |
|||
25
H A D G E H O G s
27.12.19
✎
13:55
|
(23) Какая разница, чем читать, grep или чтениетекста?
|
|||
26
pechkin
27.12.19
✎
13:56
|
(18) лучше соттвествие юзать для поиска. всетаки константное время у нее
|
|||
27
pechkin
27.12.19
✎
13:56
|
(25) скорость работы
|
|||
28
H A D G E H O G s
27.12.19
✎
13:57
|
(27) grep выходит из процессора и поддталкивает жесткий диск?
|
|||
29
pechkin
27.12.19
✎
13:58
|
(28) многопоточность из коробки
|
|||
30
toypaul
гуру
27.12.19
✎
14:00
|
в своей время когда делал анализатор модулей (объектов и форм) выгруженные в файлы начинал с чтения текста и его разбора. жутко медленно. потом переделал на regexp - раз в 10 наверное стало быстрее
|
|||
31
H A D G E H O G s
27.12.19
✎
14:00
|
(29) Многопоточно считывает файл и ползет по нему? Или ищет в нем?
|
|||
32
pechkin
27.12.19
✎
14:00
|
(31) 1 файл нет, но тут файлов много
|
|||
33
H A D G E H O G s
27.12.19
✎
14:02
|
(32) Шептать всех наверх. Ну так и на 1С можно сделать многопоточно.
|
|||
34
pechkin
27.12.19
✎
14:02
|
(33) так из коробки же
|
|||
35
H A D G E H O G s
27.12.19
✎
14:03
|
(34) Ну тоесть, 1С вообще не использовать?
|
|||
36
pechkin
27.12.19
✎
14:03
|
(35) для фильтра файлов - нет
|
|||
37
H A D G E H O G s
27.12.19
✎
14:04
|
(36) Если эти 100 юрлиц - 100 ИНН будут во всех файлах?
|
|||
38
LLIaMaH
27.12.19
✎
14:27
|
(37) Нет, щас выложат проверки на 2020 год, скачаю 12 фалов на каждый месяц, каждый файл 2гига примерно, его парсинг занимает 10гигов памяти. Пока данные такие. Пока вот споткнулся на парсинге, занимает дофига времени и памяти.
|
|||
39
LLIaMaH
27.12.19
✎
14:28
|
нада просто понять наши 100 юр лиц есть в этих файлах и когда будут проверки, так или иначе каждый месяц ктото есть.
|
|||
40
Fragster
гуру
27.12.19
✎
14:29
|
если ИНН на условно верхнем уровне, то можно через чтение доходить до него, проверять и дальше пропускать или там уже использовать фабрику - на вложенный узел.
|
|||
41
Fragster
гуру
27.12.19
✎
14:31
|
тогда памяти будет не в пример меньше использоваться. я так XML для яндекс маркета лепил при ограничении 32 гига на скрипт и 15к наименований на похапэ
|
|||
42
Fragster
гуру
27.12.19
✎
14:31
|
32 метра, естественно
|
|||
43
LLIaMaH
27.12.19
✎
14:35
|
(40) Да я не работал толком с ХМЛ, читал статьи, копипастил варианты из интерента, а что за что отвечает и может делать в 1С по части ХМЛ я не знаю. Попробую покапать в направлении ЧтенияХМЛ
|
|||
44
Garykom
гуру
27.12.19
✎
14:42
|
Иногда нужен SAX ибо он тупо лучше подходит в отличие от DOM.
Скнирующий поиск строки в тексте быстрее чем парсинг (неважно SAX или DOM), поэтому сначала цикл по своим ИНН и файлам XML и ищем в каждом файле как в простом текстовом, лишние не парсим. |
|||
45
Garykom
гуру
27.12.19
✎
14:44
|
Еще оптимально написать свой парсер, который получив позицию ИНН в XML сначала вернется по тегам назад и возьмет начало нужного блока а затем и конец.
|
|||
46
lodger
27.12.19
✎
14:49
|
(45) зачем писать, когда есть RegExp и (16) ?
|
|||
47
Garykom
гуру
27.12.19
✎
14:51
|
(46)
1. Регулярка медленней и не так надежна как свой парсер. 2. Я проспал встроенные RegExp в 1С ? |
|||
48
LLIaMaH
27.12.19
✎
14:58
|
А можно как-то превратить позицию в текстовом файле в чето структурное, без написания своего парсинга, Я знаю имена тегов в которые обернута сущность "Проверка прокуратуры", в этих тегах может лежать мой ИНН, если я найду позицию своего ИНН я могу найти и начальный тег и завершающий. Както можно этот кусок без гемороя превратить в чето структурное. Может вырезать кусок теста и скормить фабрике или чето подобное.
|
|||
49
Fragster
гуру
27.12.19
✎
15:00
|
еще можно https://marketplace.visualstudio.com/items?itemName=CDATASOFTWARE.XMLODBCDriver и запросы с отбором in (...) сделать, получив только нужные данные в один проход. но это не точно :))
|
|||
50
lodger
27.12.19
✎
15:00
|
(47) поиск циферок
scrptCtrl = Новый ComОбъект("MSScriptControl.ScriptControl"); scrptCtrl.Language="vbscript"; scrptctrl.Addcode("Function VBS_Just_Digit(Str) | Set objRegExp = New RegExp | objRegExp.Pattern = ""[^\d]"" | objRegExp.Global = true | VBS_Just_Digit = objRegExp.Replace(Str, """") |End Function"); Результат = ScrptCtrl.Run("VBS_Just_Digit", Str); |
|||
51
Fragster
гуру
27.12.19
✎
15:00
|
и вот еще https://www.progress.com/odbc/xml
|
|||
52
Fragster
гуру
27.12.19
✎
15:01
|
(50) это не оптимально будет
|
|||
53
lodger
27.12.19
✎
15:04
|
(52) а ты налей и отойди ©
|
|||
54
LLIaMaH
27.12.19
✎
15:04
|
Мне кажется регулярка не пройдет, там сложная схема узла, атрибуты могут быть, могут не быть, в зависимости от разных условий, вместо одних атрибутов могут быть списки этих атрибутов, например я столкнулся, что адрес объекта проверки может быть как обектХДТО так может быть как СписокХДТО когда компания имеет много адресов.
|
|||
55
Garykom
гуру
27.12.19
✎
15:05
|
(50) У меня linux и?
|
|||
56
lodger
27.12.19
✎
15:06
|
(54) но ведь вся эта требуха идёт вместе с инн в одном блоке?
тащи блок, потом читать его будешь. |
|||
57
LLIaMaH
27.12.19
✎
15:07
|
(56) вот я и сравшиваю, можно ли скормить вырезаную строку парсеру? Я бы уже попробовал но не у компа пока.
|
|||
58
Fragster
гуру
27.12.19
✎
15:07
|
(54) это всегда список, просто у тебя схемы нет
|
|||
59
Garykom
гуру
27.12.19
✎
15:08
|
Короче ТС если надо то дай плиз xml файлик и я те набросаю код на go для твоей задачки
|
|||
60
H A D G E H O G s
27.12.19
✎
15:09
|
Да, ТС, дай Егору сделать удаление геммороя через гланды.
|
|||
61
Garykom
гуру
27.12.19
✎
15:09
|
(59)+ Будет запустить программку с указанием порта, она поднимает свой веб-сервер на этом порту и из 1С тупо HTTPСоединение куда кидается xml и список ИНН, в ответ результат
|
|||
62
Garykom
гуру
27.12.19
✎
15:10
|
(60) Ха. Тут есть мелкий момент что Golang'а идеально подходит для подобных задачек.
|
|||
63
H A D G E H O G s
27.12.19
✎
15:11
|
ТС, начни с приобретения компа.
Потом читай файл и ищи потегово. Находи ИНН и ищи в индексированной ТЗ. Под каждый файл создавай ФоновоеЗадание |
|||
64
Fragster
гуру
27.12.19
✎
15:11
|
(57) не вырезанную строку, а узел ему скормить можно. но тогда у тебя будет строго последовательный доступ к кускам. например для структуры
<root><branch>...</branch><branch>...</branch><branch>...</branch><branch>...</branch><branch>...</branch></root> можно либо сразу пихнуть в объект, либо Чтение.ПерейтиКСодержимому() до уровня, пока Чтение.Имя не станет равно branch и уже тогда делать Фабрика.ПрочитатьXML (в цикле), тогда фабрика будет читать (и проходить по чтению) по одному объекту branch и, соответственно, не жрать память. |
|||
65
Garykom
гуру
27.12.19
✎
15:13
|
(64) А если там в каждом файлике несколько лямов <branch> ?
|
|||
66
LLIaMaH
27.12.19
✎
15:14
|
да ладно, я щас на работе запустил вариант обработки через полный последовательный парсинг всех фалов, вроде работает и поехал домой, должно работать, парсит тока каждый файл минту по 15 и + 12гигов памяти. Обрабтывает очень быстро потом. Если получиться, то без доп требований заказчика пока оставлю так, просто на будщее хочу сам разобраться.
|
|||
67
Fragster
гуру
27.12.19
✎
15:15
|
(65) ну запусти по фоновому на каждый файлик и вперед
|
|||
68
Fragster
гуру
27.12.19
✎
15:16
|
память-то жрать оно не будет
|
|||
69
LLIaMaH
27.12.19
✎
15:16
|
(63) а суммарно все фоновые процесы не сожрут 100 гигов и положат сервер? памяти всего 160 гигов :)
|
|||
70
H A D G E H O G s
27.12.19
✎
15:25
|
(69) Не сожрат. На правильном сервере сервер 1С ограничен по памяти
|
|||
71
Garykom
гуру
27.12.19
✎
15:29
|
Терь понятно почему ваша 1С тормозит и сервера падают ))
|
|||
72
RomanYS
27.12.19
✎
17:02
|
(63) Для задачи в (0) (условно 100 ИНН в гиговом файле) обход списка ИНН и поиск их по строке (целиком содержащей) файл явно быстрее будет чем последовательный (любыми средствами) парсинг и проверка на вхождение в список.
Затестил СтрНайти в файле: в среднем поиск 1 ИНН меньше секунды (0.7-0.9) https://proverki.gov.ru/wps/portal/!ut/p/z1/pZJfTsJAEMavwguPMFNA_vgGGgkGg2AQ2hezlKFU2m6zLBXePIB38AgS1MSY6BmWG9lFopIgatxsMjubb34z32bBgi5YAYtch0mXB8yLc9PKX9RqxZpRReOkmC0dYBOPKrnqeQsRC9BZCXBjlbHSylSyiNVGBqy_138l_a5-h8Daje-AtUWy6eAnxjFYjsd7789VDnrZogOWoAEJEumJiK-HUobj_SQmccaCPk3TYpLEbeohH0vofohW9grf2svloSNozCfCJmg5JBshBYdMspokvx03btrMHlKdIvJOmUNwps3MiAkwM2iUdOa5wQjMzwFDwSMSIzft8Gg1Jo-Z_ZiZxELBQCOXNzCTcoNxSLb-JCkNShnpqe9p3BX1dOP_AzXM54Ecgrk6D7jwmQRz3Ue60iMw1e3yWr2qhXqM47N6SqgXNU-ouzgs1Hx5vbxJaFxC3ceqBzXXpW4fzFwJQr_d7uLlnhfVB37ZL2bX-w2Uevej/dz/d5/L0lHSklKQ1NDbEtLVUpDZ3BSQ2dwUkNncFJDZ3BSSWshL1lEWUVBQUlNRUFBQUVFTUNNS0dJTUFPRU9NRUdCRUJFSkZORk5KRkRMRExKREhQSFBKSEFvZ29wQWlLQS80SkNpaksxYkdMamlFRXBNaFJSVWs1Q2ltcHB5RkROU3prS09hbmxWUkNnIS9aN19JSThJMUcwMU04MzlDMFEwRkI0R1ZSMDA0NS9aNl9JSThJMUcwMU04MzlDMFEwRkI0R1ZSMDBHNi92aWV3L21heGltaXplZC80OS90aXRsZS_Qn9GA0L7QstC10YDQutC4INC90LAg0K_QvdCy0LDRgNGMIDIwMTkg0LPQvtC00LAvbGluay9odHRwczolMCUwcHJvdmVya2kuZ292LnJ1JTBvcGVuZGF0YSUwNzcxMDE0NjEwMi1pbnNwZWN0aW9uLTIwMTktMS54bWwvZm9ybWF0L3htbC9lbl9VUw!!/ Из непонятного: размер файла 1 096 816 900 bytes кодировка utf-8 Длина строки 706 306 327 (Как так то!?) Расход памяти 1,4ГБ |
|||
73
H A D G E H O G s
27.12.19
✎
17:14
|
||||
74
RomanYS
27.12.19
✎
17:17
|
(73) Спасибо
|
|||
75
Garykom
гуру
27.12.19
✎
17:33
|
(72) Может веб-сервис замутить?
|
|||
76
lodger
27.12.19
✎
17:37
|
(75) а это кстати идея, да. тебе то не надо искать в xml одноразово как (0), тебе можно загрузить его в РегСвед и там поиски\отборы делать.
|
|||
77
Fragster
гуру
27.12.19
✎
17:37
|
(72) теперь добавьте сюда вычленение и обработку сопутствующей информации. автору не просто найти ИНН в файле нужно.
|
|||
78
Garykom
гуру
27.12.19
✎
17:43
|
(76) Нах-нах, у меня go и я сча думаю как эту хрень автоматом новые файлики скачивать и подгружать в базу sql
|
|||
79
Garykom
гуру
27.12.19
✎
17:48
|
(78)+ Разобрался https://i.paste.pics/940283398b86ea82d3ce9d45ccce6a30.png
|
|||
80
Дык ё
27.12.19
✎
17:49
|
(13) а как же xpath? :)
|
|||
81
Garykom
гуру
27.12.19
✎
17:51
|
(79)+ Сначала https://proverki.gov.ru/opendata/list.xml
Далее парсишь и качаешь планы, из планов уже конкретные данные |
|||
82
lodger
27.12.19
✎
17:54
|
(78) "это выражаясь в терминах 1с".
конечно ж в скуль, а язык уже дело вкуса. это если упражняться в программировании охота, а можно напрячь какую-нибудь шайтан коробку типа эластика. |
|||
83
Garykom
гуру
27.12.19
✎
18:06
|
(82) Што за "эластик" ?
|
|||
84
RomanYS
27.12.19
✎
19:48
|
(77)
1. Нужных вхождений будет немного 2. СтрНайти работает и назад - найти начальный тег без проблем |
|||
85
xXeNoNx
27.12.19
✎
19:57
|
||||
86
NcSteel
27.12.19
✎
20:13
|
Открыть файл блокнотом и глазками пробежать.
|
|||
87
RomanYS
27.12.19
✎
20:15
|
(86) блокнот ругается "...too large...". В файле даже переносов нет, в одну строку 1,5 млрд символов))
|
|||
88
NcSteel
27.12.19
✎
20:21
|
(87) Значит взять блокнот ++ и им смотреть. Это все отмазки что файл большой, что бы компьютер не покупать современный
|
|||
89
RomanYS
27.12.19
✎
20:47
|
(88) Сколько символов ты можешь "глазками пробежать" в секунду/минуту/час/день/месяц/год7
|
|||
90
Garykom
гуру
27.12.19
✎
20:57
|
(85) А нафуй она нужна в данной задаче? Про неё я слышал но совершенно не понял зачем она тут.
Один хрен xml скачивать и парсить надо, а раз так то проще в базу загнать и просто по полю ИНН искать |
|||
91
RomanYS
27.12.19
✎
21:01
|
(90) Если у тебя миллионы запросов (ИНН), тогда загонять в SQL вероятно оптимальный вариант. А если запросов сотня, то имхо СтрНайти наше всё
|
|||
92
Garykom
гуру
27.12.19
✎
21:13
|
(91) Да (75) хочу для портфолио на Go, тут как раз оптимально загружать в базу редко изменяемые xml и выложить на сайт api в который ИНН можно один или списком а оно в ответ готовый результата в JSON или XML отобранное.
|
|||
93
Garykom
гуру
27.12.19
✎
21:14
|
(92)+ Исходники на гитхаб, кому надо тот сам скачает и у себя развернет сервису, да и поправит если что
|
|||
94
Кирпич
28.12.19
✎
11:27
|
таки скатились на вебсервисы и джисон с потоками
|
|||
95
Garykom
гуру
28.12.19
✎
15:27
|
(94) Таки не предназначена 1С для подобных задач и плохо с такими объемами файлов справляется.
1С она для другого заточена. |
|||
96
Злопчинский
28.12.19
✎
15:41
|
а вопрос - эти все обработки - они что у тс - каждые полчаса выполняются? если это разовые просчеты - то не один хрен будет это час считаться или полтора?
|
|||
97
Garykom
гуру
28.12.19
✎
15:49
|
(96) Тут вопрос передачи этой хрени юзерам в продакшен, пусть даже раз в месяц 12*15 мин это дохрена.
Т.е. юзер запускает обработку/отчет по проверке, оно скачивает xml и ищет свои ИНН и как понимаем когда с момента запуска до ответа юзеру проходит несколько часов это редкостный изврат. |
|||
98
Кирпич
28.12.19
✎
16:10
|
(97) да там на сайте вроде есть куда вбить ИНН и получить результат
|
|||
99
Djelf
28.12.19
✎
16:11
|
Медленно читает golang через encoding/xml, медленно... xpatch возможно быстрее будет.
https://cloud.mail.ru/public/44Tt/5fVbNMSgM go_conversion.exe input.xml output.db3 хмл 1096816900 байт, обработка сжирает 2гб оперативки, 40с, 77652записей, 1942 записей/с, на выходе база sqlite3 (только инн и дата проверки). Интересно на сколько было бы на си быстрее и насколько дольше это писать ;)
|
|||
100
Garykom
гуру
28.12.19
✎
16:16
|
(99) У ТС 1С читает 15 минут один файлик xml, так что 40с на голанг это не сказал бы что медленно.
|
|||
101
Garykom
гуру
28.12.19
✎
16:18
|
(99) На С или С++ это пипец писать, да можно конечно Qt классы на C++ заюзать или нечто похожее но один хрен долго писать.
А выполняться будет не фиг быстрее, но можно на С++ сделать чтобы жрало сильно меньше. |
|||
102
Garykom
гуру
28.12.19
✎
16:27
|
(99) Кста если https://github.com/jmoiron/sqlx заюзать то код еще короче будет и удобней
|
|||
103
Garykom
гуру
28.12.19
✎
16:30
|
(102) гайды
http://jmoiron.github.io/sqlx/ https://blog.maddevs.io/golang-mysql-9aa09cdbb666 Очень удобно когда тексты sql отдельно вынесены и оно сразу с json само маршалит |
|||
104
Djelf
28.12.19
✎
18:04
|
(101) На golang тоже не проблема сделать чтобы меньше кушало.
Правда не 40с, а 45с, но зато <50 метров оперативки ;) В сравнении с 1С это несомненная победа!
|
|||
105
RomanYS
28.12.19
✎
19:13
|
(104) ЧтениеТекста в 1С тоже прекрасно читает порциями. Память расходуется на прочитанную часть строки. По времени конечно 1С проиграет
|
|||
106
v77
28.12.19
✎
21:31
|
(99) не надо xml парсить и будет быстро. за пару секунд гиг перелопатит
|
|||
107
v77
28.12.19
✎
22:08
|
Вот на питоне делает то же что и (99). Парсит гиговый файл и добавляет в sqlite ИНН и дату. На моем ноуте 3-4 секунды. А если просто найти нужный ИНН, еще быстрее будет.
|
|||
108
Garykom
гуру
28.12.19
✎
22:10
|
(107) Ах ты хитрая же жопа которая xml как текстовый файл с ключевыми подстроками юзает и гордится этим.
Нет уж сделай классический парсинг XML по тегам и сравним время. |
|||
109
v77
28.12.19
✎
22:18
|
(108) я ж тебе говорю, что не надо парсить. так быстрее. сам ты жопа :)
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |