Address FIAS in the PostgreSQL environment. Part 3
This is the third part of the article that describes the search function in the list adresovana
elements of the FIAS that are loaded into a database under PostgreSQL. Here are links to first and second part.
/ >
The full text of the article is composed of 4 parts. In the first half of this part of the article provides comments on the implementation of the function. The second source text of the function. Those readers who are only interested in the source code, we offer go directly to Application.
the
Function fstf_AddressObjects_SearchByName designed to search hadrobregmus elements of FIAS for their names. The search can osushestvlyaetsya not only by name and type of the current element, but also the names and types of one or two of his immediate ancestors.
Consider a few examples. For a start, find all adresaroj elements the title of which the word "Mushroom".
the table 8. The function execution result fstf_AddressObjects_SearchByName('Mushroom')
the
The result is nothing unexpected, except for clear evidence of benefit from the function of creating the full name.
Now let's modify the query. Find all adresaroj elements in the title of the nearest ancestor include the word "Mushroom".
the table 9. The function execution result fstf_AddressObjects_SearchByName
(NULL,NULL,'Mushroom')
the
The result of this query is somewhat more unexpected, since the names found adresovany elements there is no word "Mushroom" but it is in the name of their ancestor.
And finally, consider search by name of the ancestor, which must have the word "Achinsk", and in the name of his grandson needs to be part of "OSM". Here we have used a special character is an underscore "_". This symbol indicates that on its place there can be any single character. Here it is applied to find not just the items with the names "lake" or "lake" and "lake" or "lake".
the table 9. The function execution result fstf_AddressObjects_SearchByName(NULL,NULL,'Mushroom')
the
The query found the street, lake and lane lake in the three settlements Achinsk and Kazachinsko districts of the Krasnoyarsk region. The text function, see Application "Create function fstf_AddressObjects_SearchByName".
the
If the value has only the first two arguments – name (a_FormalName) and type (a_ShortName) adresource element, the search is performed in all entries of the table fias_AddressObjects. Previously the values of the passed parameters are converted to uppercase, spaces replaced with " % " symbol. The same symbol surrounded the value to the right and to the left. Thus converted values are used in the search query as part of the operation LIKE. An example of such query is shown in Fig. 4.

the Fig. 4. A simple search adresource element.
Condition select CurrStatus was discussed in the first part of the article under "Genealogy adresource elements" "How it works".
To search by title and type of the parent adresource element must be set to at least one of two arguments: the third (a_ParentFormalName), or fourth (a_ParentShortName). In this case, the search is performed in all the table entries, received by the connection (INNER JOIN) of all records fias_AddressObjects records adresource parent element on the basis of pfa.AOGUID=cfa.ParentGUID.
An example of such query is shown in Fig. 5.

the Fig. 5. Search by name and type adresource parent element.
Pre-treatment values of the input parameters is carried out according to the same rules as in the case of a simple search. To search by title and type of grandparent adresource element must be set to at least one of two arguments: the fifth (a_GrandParentFormalName) or sixth (a_GrandParentShortName). In this case, the search is performed in all entries in the table received a double connection (INNER JOIN) of all records fias_AddressObjects records of parent and grandparent adresovana elements. An example of such query is shown in Fig. 6.

the Fig. 6. Search by title and type of grandparent adresource element.
Pre-treatment values of the input parameters is carried out according to the same rules as in the case of the simple search.
the
the
the
Thank you for your attention!
Article based on information from habrahabr.ru
elements of the FIAS that are loaded into a database under PostgreSQL. Here are links to first and second part.
/ >

The full text of the article is composed of 4 parts. In the first half of this part of the article provides comments on the implementation of the function. The second source text of the function. Those readers who are only interested in the source code, we offer go directly to Application.
the
Search adresource
Function fstf_AddressObjects_SearchByName designed to search hadrobregmus elements of FIAS for their names. The search can osushestvlyaetsya not only by name and type of the current element, but also the names and types of one or two of his immediate ancestors.
Consider a few examples. For a start, find all adresaroj elements the title of which the word "Mushroom".
the table 8. The function execution result fstf_AddressObjects_SearchByName('Mushroom')
AOGUID | AOLevel | Full address | ShortName | FormalName | CurrStatus | ActStatus |
---|---|---|---|---|---|---|
15faf08c-78b6-4b92-8a56-2ff70f2c4cab | 6 | Achinskiy R-n, p Fungal | p | Mushroom | 0 | 1 |
f1772172-4dd1-449d-b2d2-ab96883d8871 | 7 | kezhemskogo R-n, g Kodinsk, per Mushroom | pen | Mushroom | 0 | 1 |
146cbcb5-4ad9-4578-916f-80ebd5c2b846 | 7 | Emel R-n, p Elite, per Mushroom | pen | Mushroom | 0 | 1 |
a8ee8caf-fd5f-489c-92d9-f560e3f93c8b | 7 | Sukhobuzimskiy R-n, d Shestakovo, per Mushroom | pen | Mushroom | 0 | 1 |
84f4baa8-1db2-471d-967d-20d489bca68e | 7 | kuraginskiy R-n, with Thtat, per Mushroom | pen | Mushroom | 0 | 1 |
1f2b7975-ce05-4627-bd13-d8d6228accd7 | 7 | g Sorsk, per Mushroom | pen | Mushroom | 0 | 1 |
The result is nothing unexpected, except for clear evidence of benefit from the function of creating the full name.
Now let's modify the query. Find all adresaroj elements in the title of the nearest ancestor include the word "Mushroom".
the table 9. The function execution result fstf_AddressObjects_SearchByName
(NULL,NULL,'Mushroom')
AOGUID | AOLevel | Full address | ShortName | FormalName | CurrStatus | ActStatus | Parent ShortName | Parent FormalName |
---|---|---|---|---|---|---|---|---|
45064ade-a0a7-4258-88c8-baa57094aa2d | 7 | Achinskiy R-n, p Fungal, ul Zheleznodorozhnaya | ul | Train | 0 | 1 | p | Mushroom |
ba4ec53c-50b7-4325-866a-81f97a38214c | 7 | Achinskiy R-n, p Fungal, ul Zapadnaya | ul | West | 0 | 1 | p | Mushroom |
d6e9e0cc-e944-4deb-a09c-c545af691836 | 7 | Achinskiy R-n, p Fungal, ul North | ul | North | 0 | 1 | p | Mushroom |
5ae71e68-5477-446b-b878-0a9c9bf3bdcd | 7 | Achinskiy R-n, p Fungal, ul South | ul | South | 0 | 1 | p | Mushroom |
The result of this query is somewhat more unexpected, since the names found adresovany elements there is no word "Mushroom" but it is in the name of their ancestor.
And finally, consider search by name of the ancestor, which must have the word "Achinsk", and in the name of his grandson needs to be part of "OSM". Here we have used a special character is an underscore "_". This symbol indicates that on its place there can be any single character. Here it is applied to find not just the items with the names "lake" or "lake" and "lake" or "lake".
the table 9. The function execution result fstf_AddressObjects_SearchByName(NULL,NULL,'Mushroom')
AOGUID | AOLevel | Full address | ShortName | FormalName | CurrStatus | ActStatus | Parent ShortName | Grand Parent ShortName | Grand Parent FormalName | |
---|---|---|---|---|---|---|---|---|---|---|
715eef9d-48f6-4322-bcaa-9d239e89b7e4 | 7 | Achinskiy R-n, d Barabanovo, per lake | pen | lake | 0 | 1 | d | Baranovka | rn | Achinsk |
05c7b2ad-e405-4c8b-9503-6761971e858e | 7 | Achinskiy R-n, d'inka, ul Ozernaya | ul | lake | 0 | 1 | d | main | rn | Achinsk |
bdfcd515-1851-4caf-83ba-12ee79f9f6a7 | 7 | kazachinskiy R-n, with Dudivka, ul Ozernaya | ul | lake | 0 | 1 | Dudivka | rn | Kazachinsko |
The query found the street, lake and lane lake in the three settlements Achinsk and Kazachinsko districts of the Krasnoyarsk region. The text function, see Application "Create function fstf_AddressObjects_SearchByName".
the
How it works
If the value has only the first two arguments – name (a_FormalName) and type (a_ShortName) adresource element, the search is performed in all entries of the table fias_AddressObjects. Previously the values of the passed parameters are converted to uppercase, spaces replaced with " % " symbol. The same symbol surrounded the value to the right and to the left. Thus converted values are used in the search query as part of the operation LIKE. An example of such query is shown in Fig. 4.

the Fig. 4. A simple search adresource element.
Condition select CurrStatus was discussed in the first part of the article under "Genealogy adresource elements" "How it works".
To search by title and type of the parent adresource element must be set to at least one of two arguments: the third (a_ParentFormalName), or fourth (a_ParentShortName). In this case, the search is performed in all the table entries, received by the connection (INNER JOIN) of all records fias_AddressObjects records adresource parent element on the basis of pfa.AOGUID=cfa.ParentGUID.
An example of such query is shown in Fig. 5.

the Fig. 5. Search by name and type adresource parent element.
Pre-treatment values of the input parameters is carried out according to the same rules as in the case of a simple search. To search by title and type of grandparent adresource element must be set to at least one of two arguments: the fifth (a_GrandParentFormalName) or sixth (a_GrandParentShortName). In this case, the search is performed in all entries in the table received a double connection (INNER JOIN) of all records fias_AddressObjects records of parent and grandparent adresovana elements. An example of such query is shown in Fig. 6.

the Fig. 6. Search by title and type of grandparent adresource element.
Pre-treatment values of the input parameters is carried out according to the same rules as in the case of the simple search.
the
the APPLICATION
the
Create function fstf_AddressObjects_SearchByName
the
BEGIN TRANSACTION;
DROP FUNCTION IF EXISTS fstf_AddressObjects_SearchByName(
a_FormalName VARCHAR(150), a_ShortName VARCHAR(20),
a_ParentFormalName VARCHAR(150),a_ParentShortName VARCHAR(20),
a_GrandParentFormalName VARCHAR(150),a_GrandParentShortName VARCHAR(20));
/************************************************************************/
/* Returns a search result in the list adresovana elements FIAS */
/* by their name and type */
/***********************************************************************/
CREATE OR REPLACE FUNCTION fstf_AddressObjects_SearchByName(
a_FormalName VARCHAR(150), /* Optimized for the search name */
/* adresource element*/
a_ShortName VARCHAR(20) default NULL, /* Short name */
/*adresource element */
a_ParentFormalName VARCHAR(150) default NULL, /* Optimized for search */
/* name adresource element*/
a_ParentShortName VARCHAR(20) default NULL, /* Short name */
a_GrandParentFormalName VARCHAR(150) default NULL, /*Optimized for search */
/* name adresource element*/
a_GrandParentShortName VARCHAR(20) default NULL, / * Short name */
/* adresource element */
)
RETURNS TABLE (rtf_AOGUID VARCHAR(36),
rtf_AOLevel INTEGER,
rtf_AddressObjectsFullName VARCHAR(1000),
rtf_ShortName VARCHAR(20),
rtf_FormalName VARCHAR(150),
rtf_CurrStatus INTEGER,
rtf_ParentShortName VARCHAR(20),
rtf_ParentFormalName VARCHAR(150),
rtf_GrandParentShortName VARCHAR(20),
rtf_GrandParentFormalName VARCHAR(150))
AS
$BODY$
DECLARE
c_WildChar CONSTANT VARCHAR(2)='%';
c_BlankChar CONSTANT VARCHAR(2)=' ';
v_FormalNameTemplate VARCHAR(150); /* Pattern to search for names */
/* adresource element*/
v_ShortNameTemplate VARCHAR(20); /* Pattern type */
/* adresource element */
v_ParentFormalNameTemplate VARCHAR(150); /* Pattern to search for names */
/* adresource parent element*/
v_ParentShortNameTemplate VARCHAR(20); /* Pattern to search for the type of parent */
/* adresource element */
v_GrandParentFormalNameTemplate VARCHAR(150); /* Pattern to search for */
/* names adresource parent element*/
v_GrandParentShortNameTemplate VARCHAR(20); /* Pattern type */
/* adresource parent element */
--************************************************************
--************************************************************
BEGIN
v_ShortNameTemplate:=UPPER(COALESCE(c_WildChar||
REPLACE(TRIM(a_ShortName),c_BlankChar,c_WildChar)||
c_WildChar,c_WildChar));
v_FormalNameTemplate:=UPPER(c_WildChar||
REPLACE(TRIM(a_FormalName),c_BlankChar,c_WildChar)||
c_WildChar);
IF a_ParentFormalName IS NULL AND a_ParentShortName IS NULL
AND a_GrandParentFormalName IS NULL
AND a_GrandParentShortName IS NULL THEN
RETURN QUERY
SELECT cfa.AOGUID,cfa.AOLevel,
fsfn_AddressObjects_TreeActualName(cfa.AOGUID),
cfa.ShortName,cfa.FORMALNAME,
cfa.currstatus,NULL::VARCHAR,NULL::VARCHAR,
NULL::VARCHAR,NULL::VARCHAR
FROM fias_AddressObjects cfa
WHERE cfa.currstatus=
CASE WHEN 0 < ALL(SELECT iao.currstatus FROM fias_AddressObjects iao
WHERE cfa.aoguid = iao.aoguid)
THEN (SELECT MAX(iao.currstatus) FROM fias_AddressObjects iao
WHERE cfa.aoguid = iao.aoguid)
ELSE 0
END
AND UPPER(cfa.FORMALNAME) LIKE v_FormalNameTemplate
AND UPPER(cfa.ShortName) LIKE v_ShortNameTemplate
ORDER BY the cfa.AOLevel,cfa.ShortName,cfa.FORMALNAME;
ELSIF a_ParentFormalName IS NOT NULL
AND a_GrandParentFormalName IS NULL
AND a_GrandParentShortName IS NULL THEN
v_ParentShortNameTemplate:=UPPER(COALESCE(c_WildChar||
REPLACE(TRIM(a_ParentShortName),c_BlankChar,c_WildChar)||
c_WildChar,c_WildChar));
v_ParentFormalNameTemplate:=UPPER(c_WildChar||
REPLACE(TRIM(a_ParentFormalName),c_BlankChar,c_WildChar)||
c_WildChar);
v_FormalNameTemplate:=COALESCE(v_FormalNameTemplate,c_WildChar);
RETURN QUERY
SELECT cfa.AOGUID,cfa.AOLevel,fsfn_AddressObjects_TreeActualName(cfa.AOGUID),
cfa.ShortName,cfa.FORMALNAME,cfa.currstatus,
pfa.ShortName,pfa.FORMALNAME,
NULL::VARCHAR,NULL::VARCHAR
FROM fias_AddressObjects pfa
INNER JOIN fias_AddressObjects ON cfa and pfa.AOGUID=cfa.ParentGUID
WHERE cfa.currstatus=CASE WHEN 0 <
ALL (SELECT iao.currstatus FROM fias_AddressObjects iao
WHERE cfa.aoguid = iao.aoguid)
THEN (SELECT MAX(iao.currstatus) FROM fias_AddressObjects iao
WHERE cfa.aoguid = iao.aoguid)
ELSE 0 END
AND pfa.currstatus=CASE WHEN 0 <
ALL(SELECT iao.currstatus FROM fias_AddressObjects iao
WHERE pfa.aoguid = iao.aoguid)
THEN (SELECT MAX(iao.currstatus) FROM fias_AddressObjects iao
WHERE pfa.aoguid = iao.aoguid)
ELSE 0 END
AND UPPER(pfa.FORMALNAME) LIKE v_ParentFormalNameTemplate
AND UPPER(pfa.ShortName) LIKE v_ParentShortNameTemplate
AND UPPER(cfa.FORMALNAME) LIKE v_FormalNameTemplate
AND UPPER(cfa.ShortName) LIKE v_ShortNameTemplate
ORDER BY pfa.ShortName,pfa.FORMALNAME,
cfa.AOLevel,cfa.ShortName,cfa.FORMALNAME;
ELSE
v_GrandParentShortNameTemplate:=UPPER(COALESCE(c_WildChar||
REPLACE(TRIM(a_GrandParentShortName),c_BlankChar,c_WildChar)||
c_WildChar,c_WildChar));
v_GrandParentFormalNameTemplate:=UPPER(c_WildChar||
REPLACE(TRIM(a_GrandParentFormalName),c_BlankChar,c_WildChar)||
c_WildChar);
v_ParentShortNameTemplate:=COALESCE(UPPER(COALESCE(c_WildChar||
REPLACE(TRIM(a_ParentShortName),c_BlankChar,c_WildChar)||
c_WildChar,c_WildChar)),c_WildChar);
v_ParentFormalNameTemplate:=COALESCE(UPPER(c_WildChar||
c_WildChar),c_WildChar);
v_FormalNameTemplate:=COALESCE(v_FormalNameTemplate,c_WildChar);
RETURN QUERY
SELECT cfa.AOGUID,cfa.AOLevel,fsfn_AddressObjects_TreeActualName(cfa.AOGUID),
cfa.ShortName,cfa.FORMALNAME,
cfa.currstatus,pfa.ShortName,pfa.FORMALNAME,
gpfa.ShortName,gpfa.FORMALNAME
FROM fias_AddressObjects gpfa
INNER JOIN fias_AddressObjects pfa ON gpfa.AOGUID=pfa.ParentGUID
INNER JOIN fias_AddressObjects ON cfa and pfa.AOGUID=cfa.ParentGUID
WHERE cfa.currstatus=CASE WHEN 0 <
ALL(SELECT iao.currstatus FROM fias_AddressObjects iao
WHERE cfa.aoguid = iao.aoguid)
THEN (SELECT MAX(iao.currstatus) FROM fias_AddressObjects iao
WHERE cfa.aoguid = iao.aoguid)
ELSE 0 END
AND pfa.currstatus=CASE WHEN 0 <
ALL(SELECT iao.currstatus FROM fias_AddressObjects iao
WHERE pfa.aoguid = iao.aoguid)
THEN (SELECT MAX(iao.currstatus) FROM fias_AddressObjects iao
WHERE pfa.aoguid = iao.aoguid)
ELSE 0 END
AND gpfa.currstatus=CASE WHEN 0 <
ALL(SELECT iao.currstatus FROM fias_AddressObjects iao
WHERE gpfa.aoguid = iao.aoguid)
THEN (SELECT MAX(iao.currstatus) FROM fias_AddressObjects iao
WHERE gpfa.aoguid = iao.aoguid)
ELSE 0 END
AND UPPER(gpfa.FORMALNAME) LIKE v_GrandParentFormalNameTemplate
AND UPPER(gpfa.ShortName) LIKE v_GrandParentShortNameTemplate
AND UPPER(pfa.FORMALNAME) LIKE v_ParentFormalNameTemplate
AND UPPER(pfa.ShortName) LIKE v_ParentShortNameTemplate
AND UPPER(cfa.FORMALNAME) LIKE v_FormalNameTemplate
AND UPPER(cfa.ShortName) LIKE v_ShortNameTemplate
ORDER BY gpfa.ShortName,gpfa.FORMALNAME,
pfa.ShortName,pfa.FORMALNAME,
cfa.AOLevel,cfa.ShortName,cfa.FORMALNAME;
END IF;
END; $BODY$
LANGUAGE plpgsql;
COMMENT ON FUNCTION fstf_AddressObjects_SearchByName(
a_FormalName VARCHAR(150),a_ShortName VARCHAR(20),
a_ParentFormalName VARCHAR(150),a_ParentShortName VARCHAR(20),
a_GrandParentFormalName VARCHAR(150),a_GrandParentShortName VARCHAR(20))
IS 'Returns a search result in the list adresovana elements of FIAS by their name and type';
--ROLLBACK TRANSACTION;
COMMIT TRANSACTION;
--SELECT * FROM fstf_AddressObjects_SearchByName('BORODIN','g');
--SELECT * FROM fstf_AddressObjects_SearchByName('BORODIN');
--SELECT * FROM fstf_AddressObjects_SearchByName('two',NULL,'MIGNA');
--SELECT * FROM fstf_AddressObjects_SearchByName(NULL,NULL,'MIGNA');
--SELECT * FROM fstf_AddressObjects_SearchByName('Selma','UL',NULL);
SELECT * FROM fstf_AddressObjects_SearchByName('Selma','UL','Quartino',NULL,'record');
Thank you for your attention!