postgresql_POSTGIS

#創建數據庫
CREATE DATABASE samtest
    WITH 
    OWNER = postgres
    ENCODING = 'UTF8'
    CONNECTION LIMIT = -1;

#添加啓用postgis
-- Extension: postgis
-- DROP EXTENSION postgis;
CREATE EXTENSION postgis;
-- Extension: postgis_topology
-- DROP EXTENSION postgis_topology;
CREATE EXTENSION postgis_topology;

#創建表
-- Table: public.poi_test
-- DROP TABLE public.poi_test;
CREATE TABLE public.poi_test
(
    id bigserial NOT NULL,                          --自增加id
    name character varying(50),                         --動串
    location geometry,                              --地理信息點格式
    extinfo jsonb,                                  --其它信息
    createtime timestamp without time zone,         --時間戳
    PRIMARY KEY (id)
)
WITH (
    OIDS = FALSE
);

ALTER TABLE public.poi_test
    OWNER to postgres;


#創建geo索引 
CREATE INDEX poi_test_location_index
ON public.poi_test
USING gist
(location);

#創建jsonb索引 
CREATE INDEX public_poi_test_index_extinfo ON public.poi_test USING GIN (extinfo);

#插入表
INSERT INTO public.poi_test ( name, location,extinfo,createtime ) VALUES ( '馬泉營B口',GeomFromEWKT('SRID=4326;POINT(116.510431 40.040612)'),'{"type":"地鐵"}',current_timestamp);
INSERT INTO public.poi_test ( name, location,extinfo,createtime ) VALUES ( '漢堡啤酒餐廳',GeomFromEWKT('SRID=4326;POINT(116.511791 40.040477)'), '{"type":"飯店","ali_type":"餐廳"}',current_timestamp);
INSERT INTO public.poi_test ( name, location,extinfo,createtime ) VALUES ( '馬泉營C口停車場',GeomFromEWKT('SRID=4326;POINT(116.510691 40.039383)'), '{"type":"地鐵"}',current_timestamp);
INSERT INTO public.poi_test ( name, location,extinfo,createtime ) VALUES ( '麗苑小區',GeomFromEWKT('SRID=4326;POINT(116.516844 40.041461)'), '{"type":"小區"}',current_timestamp);

#9.4版以下,需要自定義jsonb更新函數
--start------------------------------------------------------------------------------------
/* 
 * derivative work of Matheus de Oliveira's json_manipulator.sql
 *   https://gist.github.com/matheusoliveira/9488951 
 *
 *  adapted to support postgresql 9.4 jsonb type
 *  no warranties or guarantees of any kind are implied or offered
 *
 *  license is as Matheus conferred it on 4/9/2015:
 *  matheusoliveira commented on Apr 9
 *    @hannes-landeholm, I'd like to take credit if you share them 
 *    (a link to this gist is more than enough), but I don't care 
 *    much about licensing, consider it public domain, modify and 
 *    use as you will.
 *       https://gist.github.com/matheusoliveira/9488951 
 */
--jsonb插入追加
CREATE OR REPLACE FUNCTION public.jsonb_append(data jsonb, insert_data jsonb)
RETURNS jsonb
IMMUTABLE
LANGUAGE sql
AS $$
    SELECT json_object_agg(key, value)::jsonb
    FROM (
        SELECT * FROM jsonb_each(data)
        UNION ALL
        SELECT * FROM jsonb_each(insert_data)
    ) t;
$$;
--刪除
CREATE OR REPLACE FUNCTION public.jsonb_delete(data jsonb, keys text[])
RETURNS jsonb
IMMUTABLE
LANGUAGE sql
AS $$
    SELECT json_object_agg(key, value)::jsonb
    FROM (
        SELECT * FROM jsonb_each(data)
        WHERE key <> ALL(keys)
    ) t;
$$;
--合併
CREATE OR REPLACE FUNCTION public.jsonb_merge(data jsonb, merge_data jsonb)
RETURNS jsonb
IMMUTABLE
LANGUAGE sql
AS $$
    SELECT json_object_agg(key, value)::jsonb
    FROM (
        WITH to_merge AS (
            SELECT * FROM jsonb_each(merge_data)
        )
        SELECT *
        FROM jsonb_each(data)
        WHERE key NOT IN (SELECT key FROM to_merge)
        UNION ALL
        SELECT * FROM to_merge
    ) t;
$$;
--更新
CREATE OR REPLACE FUNCTION public.jsonb_update(data jsonb, update_data jsonb)
RETURNS jsonb
IMMUTABLE
LANGUAGE sql
AS $$
    SELECT json_object_agg(key, value)::jsonb
    FROM (
        WITH old_data AS (
            SELECT * FROM jsonb_each(data)
        ), to_update AS (
            SELECT * FROM jsonb_each(update_data)
            WHERE key IN (SELECT key FROM old_data)
        )
    SELECT * FROM old_data
    WHERE key NOT IN (SELECT key FROM to_update)
    UNION ALL
    SELECT * FROM to_update
) t;
$$;

CREATE OR REPLACE FUNCTION public.jsonb_lint(from_json jsonb, ntab integer DEFAULT 0)
RETURNS jsonb
LANGUAGE sql
IMMUTABLE STRICT
AS $$
SELECT (CASE substring(from_json::text FROM '(?m)^[\s]*(.)') /* Get first non-whitespace */
        WHEN '[' THEN
                (E'[\n'
                        || (SELECT string_agg(repeat(E'\t', ntab + 1) || jsonb_lint(value, ntab + 1)::text, E',\n') FROM jsonb_array_elements(from_json)) ||
                E'\n' || repeat(E'\t', ntab) || ']')
        WHEN '{' THEN
                (E'{\n'
                        || (SELECT string_agg(repeat(E'\t', ntab + 1) || to_json(key)::text || ': ' || jsonb_lint(value, ntab + 1)::text, E',\n') FROM jsonb_each(from_json)) ||
                E'\n' || repeat(E'\t', ntab) || '}')
        ELSE
                from_json::text
END)::jsonb
$$;

CREATE OR REPLACE FUNCTION public.jsonb_unlint(from_json jsonb)
RETURNS jsonb
LANGUAGE sql
IMMUTABLE STRICT
AS $$
SELECT (CASE substring(from_json::text FROM '(?m)^[\s]*(.)') /* Get first non-whitespace */
    WHEN '[' THEN
        ('['
            || (SELECT string_agg(jsonb_unlint(value)::text, ',') FROM jsonb_array_elements(from_json)) ||
        ']')
    WHEN '{' THEN
        ('{'
            || (SELECT string_agg(to_json(key)::text || ':' || jsonb_unlint(value)::text, ',') FROM jsonb_each(from_json)) ||
        '}')
    ELSE
        from_json::text
END)::jsonb
$$;
--end------------------------------------------------------------------------------------------------------------------------------------
#全量替換更新
update public.poi_test set location=GeomFromEWKT('SRID=4326;POINT(116.510691 40.039383)') where name='馬泉營C口停車場';
update public.poi_test set extinfo='{"type":"飯店","ali_type":"餐廳"}'::jsonb where name='漢堡啤酒餐廳';
#字符串替換更新
select replace(extinfo::text,'"type": "飯店"','"type":"飯店111"')::jsonb from public.poi_test ;
update public.poi_test set extinfo=replace(extinfo::text,'"type": "飯店"','"type":"字符串替換更新"')::jsonb where name='漢堡啤酒餐廳';    
#使用自定義函數更新jsonb_update
select jsonb_update('{"type":"飯店","ali_type":"餐廳"}'::jsonb,'{"type":"1111"}'::jsonb);
update public.poi_test set extinfo=jsonb_update(extinfo::jsonb,'{"type":"自定義函數更新1"}'::jsonb) where name='漢堡啤酒餐廳';
update public.poi_test set extinfo='[{"type":"飯店","ali_type":"餐廳"}]'::jsonb where name='漢堡啤酒餐廳';
#jsonb_update
select jsonb_append('{"type":"飯店2","ali_type":"餐廳2"}'::jsonb,'{"aaa":"aaaa"}'::jsonb);
#jsonb_delete
select jsonb_delete('{"type":"飯店2","ali_type":"餐廳2"}'::jsonb,array['type']);
#jsonb_merge
select jsonb_merge('{"type":"飯店2","ali_type":"餐廳2"}'::jsonb,'{"aaaa":"合併的"}'::jsonb);



#查詢
select *,ST_AsText(location),extinfo::jsonb from public.poi_test where name like '馬泉%';
select *,ST_AsText(location) from public.poi_test where name = '麗苑小區';
select *,ST_AsText(location) from public.poi_test where extinfo @>'{"type":"地鐵"}';
select *,ST_AsText(location),extinfo->'type' as type from public.poi_test where extinfo @>'{"type":"地鐵"}';


#查詢500M內的地點,按近遠排序 
select * ,ST_Distance(GeomFromEWKT('SRID=4326;POINT(116.510431 40.040612)'), location) km from public.poi_test where ST_Distance(GeomFromEWKT('SRID=4326;POINT(116.510431 40.040612)'), location)<0.005 order by km asc;
select * ,ST_Distance(GeomFromEWKT('SRID=4326;POINT(116.510431 40.040612)'), location) km from public.poi_test where ST_Distance(GeomFromEWKT('SRID=4326;POINT(116.510431 40.040612)'), location)*1000<5 order by km asc;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章