Адреса Фиас В Среде Postgresql. Часть 1

Как бы мы ни относились к качеству адресов ФИАС, работать с ними необходимо, ведь это единственная общероссийская адресная книга.

Поэтому рано или поздно нам придется решить проблему связи местонахождения недвижимости, юридического и физического адресов с адресом из ФИАС.



Адреса ФИАС в среде PostgreSQL. Часть 1

В данной статье описан опыт работы со списком адресообразующих элементов ФИАС, загруженным в базу данных под управлением PostgreSQL. Для работы с адресообразующими элементами ФИАС создано несколько функций на языке PL/pgSQL. Полный текст статьи состоит из 4 частей.

Первая половина этой части статьи содержит комментарии по реализации функции.

Второй содержит исходный текст функции.

Тем читателям, которых интересуют только исходные тексты, мы предлагаем сразу перейти к Приложение .



Родословная адресообразующего элемента

Начнем с примера.

Вызов fstf_AddressObjects_AddressObjectTree('bfc1236d-b5d2-4734-a238-3b1e4830e963') вернет следующий список записей.

Таблица 1. Результат выполнения функции fstf_AddressObjects_AddressObjectTree

АОГИД Куррстатус Статус акта AOLevel Короткое имя Официальное имя
db9c4f8b-b706-40e2-b2b4-d31b98dcd3d1 0 1 1 край Красноярск
625497d3-22de-4390-b4b4-2febfbfc15ce 0 1 3 округ Балахтинский
39da6405-b3e6-4baf-b332-d47b73b4d5fb 0 1 6 п Могущественный
bfc1236d-b5d2-4734-a238-3b1e4830e963 0 1 7 ул.

Новый
При ближайшем рассмотрении вы заметите, что идентификатор элемента (AOGUID) «Новая улица» был передан в качестве аргумента функции, в результате чего получилось четыре записи:
  • пластинка с характеристикой самой Новой улицы;
  • три родительские записи о селе, районе и области, к которым принадлежит улица.

У функции есть еще один необязательный параметр — признак релевантности (CurrStatus), с помощью которого можно просмотреть родословную не только текущего адресообразующего элемента, но и уже устаревшего.

Полный текст функции приведен в Приложении в подразделе Создание функции fstf_AddressObjects_AddressObjectTree

С самого начала

Если вы знаете, как структурированы таблицы ФИАС, то можете пропустить этот раздел.

Необходимость такой функции продиктована тем, что список адресообразующих элементов ФИАС (ADDROBJ) представляет собой древовидную структуру, в которой каждый элемент ссылается на идентификатор (AOGUID) родительской записи по значению поля ParentGUID. .

Те.

Просматривая исходные записи списка, вы обычно видите длинный список улиц.

Чтобы определить, в каком населенном пункте находится улица, необходимо по значению ParentGUID найти записи с данным идентификатором элемента.



Адреса ФИАС в среде PostgreSQL. Часть 1

Рис.

1. Иерархия адресообразующих элементов ФИАС.

Это не опечатка и не оговорка.

По значению ParentGUID можно найти не одну, а несколько записей.

Это означает, что идентификатор элемента, формирующего адрес, не является первичным ключом для таблицы, содержащей список ADDROBJ. Дело в том, что список адресообразующих элементов вместе с каждым элементом хранит историю его «переименования».

Те.

Под одним идентификатором элемента хранится не только текущее имя элемента, но и его предыдущие имена.

То есть отдельная запись в списке ADDROBJ хранит данные об адресообразующем элементе, а также характеристики календарного периода, в течение которого название элемента было актуально.

Таблица 2. История улицы «Красноярский край, Таймырский Долгано-Ненецкий район, Дудинка, Левинские пески, Береговая улица»

Идентификатор записи AOID Идентификатор предыдущей записи PrevID Идентификатор следующей записи NextID Подписать согласно КЛАДР CurrStatus Признак релевантности ActStatus Дата начала периода StartDate Дата окончания периода EndDate
fcf51361-5494-4edc-a6bc-d5c0d471c729 2a993f3b-5743-426c-8b7d-b5c7affe49cd 0 1 25.11.2015 0:00 06.06.2079 0:00
2a993f3b-5743-426c-8b7d-b5c7affe49cd 9199c92b-18a5-431a-8b13-f54abe36e84f fcf51361-5494-4edc-a6bc-d5c0d471c729 7 0 30.09.2015 0:00 25.11.2015 0:00
9199c92b-18a5-431a-8b13-f54abe36e84f b06ff65e-aadb-42eb-9c70-a8548a40645c 2a993f3b-5743-426c-8b7d-b5c7affe49cd 6 0 28.09.2015 0:00 30.09.2015 0:00
b06ff65e-aadb-42eb-9c70-a8548a40645c a997aa7c-f2b1-4b7e-9471-5fc1f51a6752 9199c92b-18a5-431a-8b13-f54abe36e84f 5 0 08.04.2013 0:00 28.09.2015 0:00
a997aa7c-f2b1-4b7e-9471-5fc1f51a6752 b27d8e44-ade1-4dd0-b4b5-5eaa7205ff0b b06ff65e-aadb-42eb-9c70-a8548a40645c 4 0 11.01.2013 0:00 08.04.2013 0:00
b27d8e44-ade1-4dd0-b4b5-5eaa7205ff0b 327b28cc-5171-43c6-bd88-a0a2172bbf71 a997aa7c-f2b1-4b7e-9471-5fc1f51a6752 3 0 07.12.2012 0:00 11.01.2013 0:00
327b28cc-5171-43c6-bd88-a0a2172bbf71 fb7b54db-7efb-4aaf-b4cb-2364b35b80b3 b27d8e44-ade1-4dd0-b4b5-5eaa7205ff0b 2 0 01.02.2012 0:00 07.12.2012 0:00
327b28cc-5171-43c6-bd88-a0a2172bbf71 fb7b54db-7efb-4aaf-b4cb-2364b35b80b3 b27d8e44-ade1-4dd0-b4b5-5eaa7205ff0b 1 0 01.02.2012 0:00 07.12.2012 0:00
Порядок периодов релевантности имени адресообразующего элемента можно определить, просмотрев два разнонаправленных списка.

Для этого каждая запись о периоде релевантности элемента содержит два указателя на предыдущий (PrevID) и последующие периоды (NextID).

Первый период адресообразующего элемента не имеет указателя на предыдущий период, а последний (текущий) — указателя на следующий период.

Адреса ФИАС в среде PostgreSQL. Часть 1

Рис.

2. Основные поля записи адресообразующего элемента ФИАС.

Период релевантности характеризуется датами начала и окончания периода StartDate и EndDate соответственно.

При этом даты начала первого периода и окончания последнего имеют условные значения.

Датой начала первого периода принимается «01.01.1900 0:00», а датой окончания последнего (текущего) периода принимается «06.06.2079 0:00».

Текущее (действительное на данный момент) наименование адресообразующего элемента указывается в записи последнего периода при условии, что он не заполнен, т. е.

дата окончания периода больше или равна текущей дате.

Для упрощения поиска записи о текущем периоде элемента помимо даты начала и окончания периода введены еще два поля: CurrStatus и ActStatus. ActStatus принимает вполне ожидаемые значения: «1» — текущая версия характеристик элемента, «0» — не текущая или историческая версия, как указано в справочнике.

Сложнее ситуация со значениями поля CurrStatus. Используя его значения, решаются две проблемы задачи одновременно: устанавливается идентификатор каждой версии записи об адресообразующем элементе и присваивается признак релевантности записи.

Поэтому последняя текущая запись элемента содержит в этом поле значение «0», а все исторические записи нумеруются в порядке появления – «1» — самая старая запись, следующая — «2» и т.д. В таблице 2 приведен перечень записей с вариантами описания улицы Береговой в селе Левинские Пески.

В этом списке предыдущая запись текущей записи содержит цифру «7» в поле CurrStatus.

Как это работает



Адреса ФИАС в среде PostgreSQL. Часть 1

Рис.

3. Упрощенная реализация функции fstf_AddressObjects_AddressObjectTree. Для реализации функции предлагается использовать рекурсивный запрос, аналогичный показанному на рис.

3, где a_AOGUID — идентификатор адресообразующего элемента, a_CurrStatus — признак релевантности по КЛАДР.

Оба значения передаются в функцию через параметры.

Как и любой рекурсивный запрос, этот состоит из двух частей: первая часть содержит первую запись элемента с идентификатором a_AOGUID, следующая рекурсивная часть последовательно содержит все текущие родительские записи по отношению к записям, полученным в ходе предыдущих итераций.

Переход к родительскому элементу осуществляется с использованием ссылки ParentGUID текущей записи.

Здесь важно, чтобы каждая итерация приводила только к одной записи.

Для этого на значение атрибута CurrStatus накладывается ограничение.

Пример результата применения рекурсивного запроса при отсутствии уникальной записи хотя бы на одном шаге итерации показан на рис.

3. Возникает вопрос: почему ограничение на значение CurrStatus реализовано через вложенный подзапрос, а не присвоением реальных значений? Во-первых, потому что текущая запись об элементе не всегда имеет CurrStatus = 0, как показывает таблица 4. Во-вторых, функция должна возвращать результат для нерелевантных имен элементов.

В том числе даже в том случае, когда на пути между начальным и конечным элементами находится элемент, для которого не объявлена текущая запись.

Таблица 3. Результат выполнения функции над элементом с неуникальным атрибутом выбора записи

АОГИД Куррстатус Статус акта AOLevel Короткое имя Официальное имя
db9c4f8b-b706-40e2-b2b4-d31b98dcd3d1 0 1 1 край Красноярск
db9c4f8b-b706-40e2-b2b4-d31b98dcd3d1 0 1 1 край Красноярск
3d4c8618-9e22-4838-8f89-80da6851da90 0 1 3 округ Рыбинский
719b789d-2476-430a-89cd-3fedc643d821 51 0 4 г Заозерный
719b789d-2476-430a-89cd-3fedc643d821 51 1 4 г Заозерный
Если в качестве условия выбора единственной записи для элемента используется a_CurrStatus=0, то функция не будет возвращать значения для записей о городе Заозерный, записи которого приведены в таблице 4. Более того, если установить a_CurrStatus=51 , то результат будет таким, как показано в Таблице 3. Состояние:
  
   

ao.currstatus = (SELECT MIN(iao.currstatus) FROM fias_AddressObjects iao WHERE ao.aoguid = iao.aoguid)

.

который присутствует во второй части рекурсивного запроса, не совсем корректен, исходя из правила присвоения значений атрибуту CurrStatus. Действительно, если среди записей адресообразующего элемента нет текущей (CurrStatus=0), то самой «новой» является запись с максимальным, т.е.

последним использованным значением атрибута CurrStatus. При использовании вышеуказанного условия из записей неактуального элемента выбирается самая старая.

Таблица 4. Элемент с повторяющимся ненулевым значением CurrStatus.

АОГИД Куррстатус Статус акта AOLevel Короткое имя Официальное имя
719b789d-2476-430a-89cd-3fedc643d821 51 0 4 г Заозерный
719b789d-2476-430a-89cd-3fedc643d821 51 1 4 г Заозерный
Поэтому более правильным решением было бы использовать следующее условие:

ao.currstatus = CASE WHEN 0 < ALL(SELECT iao.currstatus FROM fias_AddressObjects iao WHERE ao.aoguid = iao.aoguid)

Теги: #fias #postgresql #хранимая процедура #postgresql
Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.