数码资讯
PostgreSql 使用postgis 存储地理空间信息操作以及jsonb操作示例
选购提示
关注价格、性能、续航、售后和真实使用场景,理性比较后再下单。
PostgreSql 使用postgis 存储地理空间信息操作示例
1.postgresql9.4 版本
2.请先安装postgis和postgis_topology 插件
3.jsonb操作自定义函数,9.4以前不支持jsonb单值更新
4.9.5+以解决加入了|| 和jsonb_set 等操作符和函数
#创建数据库 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'[ ' || (SELECT string_agg(repeat(E' ', ntab + 1) || jsonb_lint(value, ntab + 1)::text, E', ') FROM jsonb_array_elements(from_json)) || E' ' || repeat(E' ', ntab) || ']') WHEN '{' THEN (E'{ ' || (SELECT string_agg(repeat(E' ', ntab + 1) || to_json(key)::text || ': ' || jsonb_lint(value, ntab + 1)::text, E', ') FROM jsonb_each(from_json)) || E' ' || repeat(E' ', 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;
声明:本文内容用于数码产品信息整理与选购参考,具体价格、库存、售后政策以官方渠道和电商页面实时信息为准。