如何让json里面的value支持索引范围检索

简介:

标签

PostgreSQL , json , 索引 , gin , btree_gin , 范围检索 , 表达式索引


背景

JSON,JSONB是PG从9就开始引入的数据类型,开发人员非常喜欢,对于JSON里面的内容的检索,我们可以使用GIN索引,目前直接对JSON字段创建GIN索引,可以支持任意PATH的等值、包含检索。

https://www.postgresql.org/docs/10/static/datatype-json.html#JSON-INDEXING

但是,在多数场景中,我们可能还需要范围检索的需求,例如消费范围,年龄范围,收入范围等等。

使用表达式组合索引,很好的满足需求。

例子

单KEY,直接用btree索引

postgres=# create table test (id int, js jsonb);  
CREATE TABLE  
postgres=# create index idx_test_2 on test using btree (((js->>'key1')::int));  
CREATE INDEX  
postgres=# explain select * from test where (js->>'key1')::int between 1 and 10 ;  
                                              QUERY PLAN                                                
------------------------------------------------------------------------------------------------------  
 Index Scan using idx_test_2 on test  (cost=0.15..24.27 rows=6 width=36)  
   Index Cond: ((((js ->> 'key1'::text))::integer >= 1) AND (((js ->> 'key1'::text))::integer <= 10))  
(2 rows)  

多KEY混合,使用btree_gin, 表达式索引

例如需要查询key1,key2,key3的任意组合范围查询。

postgres=# create extension btree_gin;  
CREATE EXTENSION  
postgres=# create index idx_test_1 on test using gin (((js->>'key1')::int), ((js->>'key2')::int), ((js->>'key3')::int));  
CREATE INDEX  
postgres=# explain select * from test where (js->>'key1')::int between 1 and 10   
postgres-# ;  
                                                 QUERY PLAN                                                   
------------------------------------------------------------------------------------------------------------  
 Bitmap Heap Scan on test  (cost=24.07..33.64 rows=6 width=36)  
   Recheck Cond: ((((js ->> 'key1'::text))::integer >= 1) AND (((js ->> 'key1'::text))::integer <= 10))  
   ->  Bitmap Index Scan on idx_test_1  (cost=0.00..24.06 rows=6 width=0)  
         Index Cond: ((((js ->> 'key1'::text))::integer >= 1) AND (((js ->> 'key1'::text))::integer <= 10))  
(4 rows)  
postgres=# explain select * from test where (js->>'key1')::int between 1 and 10  or (js->>'key2')::int between 1 and 15;  
                                                                                             QUERY PLAN                                                                                               
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------  
 Bitmap Heap Scan on test  (cost=48.13..59.32 rows=13 width=36)  
   Recheck Cond: (((((js ->> 'key1'::text))::integer >= 1) AND (((js ->> 'key1'::text))::integer <= 10)) OR ((((js ->> 'key2'::text))::integer >= 1) AND (((js ->> 'key2'::text))::integer <= 15)))  
   ->  BitmapOr  (cost=48.13..48.13 rows=13 width=0)  
         ->  Bitmap Index Scan on idx_test_1  (cost=0.00..24.06 rows=6 width=0)  
               Index Cond: ((((js ->> 'key1'::text))::integer >= 1) AND (((js ->> 'key1'::text))::integer <= 10))  
         ->  Bitmap Index Scan on idx_test_1  (cost=0.00..24.06 rows=6 width=0)  
               Index Cond: ((((js ->> 'key2'::text))::integer >= 1) AND (((js ->> 'key2'::text))::integer <= 15))  
(7 rows)  
postgres=# explain select * from test where (js->>'key1')::int between 1 and 10  and (js->>'key2')::int between 1 and 15;  
                                                                                             QUERY PLAN                                                                                                
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------  
 Bitmap Heap Scan on test  (cost=40.00..44.05 rows=1 width=36)  
   Recheck Cond: ((((js ->> 'key1'::text))::integer >= 1) AND (((js ->> 'key1'::text))::integer <= 10) AND (((js ->> 'key2'::text))::integer >= 1) AND (((js ->> 'key2'::text))::integer <= 15))  
   ->  Bitmap Index Scan on idx_test_1  (cost=0.00..40.00 rows=1 width=0)  
         Index Cond: ((((js ->> 'key1'::text))::integer >= 1) AND (((js ->> 'key1'::text))::integer <= 10) AND (((js ->> 'key2'::text))::integer >= 1) AND (((js ->> 'key2'::text))::integer <= 15))  
(4 rows)  

参考

https://www.postgresql.org/docs/10/static/datatype-json.html#JSON-INDEXING

https://www.postgresql.org/docs/10/static/btree-gin.html

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍如何基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
JSON Java 关系型数据库
Java更新数据库报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
在Java中,使用mybatis-plus更新实体类对象到mysql,其中一个字段对应数据库中json数据类型,更新时报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
1859 4
Java更新数据库报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
|
JSON 关系型数据库 MySQL
MySQL全文搜索与JSON支持:高效检索与灵活数据处理
本文深入探讨了MySQL数据库中的全文搜索与JSON支持,通过详细的代码示例,阐述了全文搜索的原理、全文索引的创建,以及JSON数据类型的使用与操作。全文搜索在数据库中的重要性日益凸显,MySQL提供了全文索引来实现高效的文本数据检索,通过MATCH AGAINST语句,可以轻松地进行全文搜索操作。此外,MySQL的JSON支持为半结构化数据的存储和查询提供了灵活的解决方案,您可以存储JSON对象、数组等数据,并使用JSON函数来查询和修改数据。
1731 0
|
JSON 数据格式
LangChain-20 Document Loader 文件加载 加载MD DOCX EXCEL PPT PDF HTML JSON 等多种文件格式 后续可通过FAISS向量化 增强检索
LangChain-20 Document Loader 文件加载 加载MD DOCX EXCEL PPT PDF HTML JSON 等多种文件格式 后续可通过FAISS向量化 增强检索
1886 2
|
JSON 前端开发 JavaScript
JSON parse error: Cannot deserialize value of type `java.lang.Integer` from Boolean value
这篇文章讨论了前端Vue应用向后端Spring Boot服务传输数据时发生的类型不匹配问题,即后端期望接收的字段类型为`int`,而前端实际传输的类型为`Boolean`,导致无法反序列化的问题,并提供了问题的诊断和解决方案。
JSON parse error: Cannot deserialize value of type `java.lang.Integer` from Boolean value
|
存储 JSON Cloud Native
云原生数据仓库使用问题之怎么在ADB中添加JSON索引
阿里云AnalyticDB提供了全面的数据导入、查询分析、数据管理、运维监控等功能,并通过扩展功能支持与AI平台集成、跨地域复制与联邦查询等高级应用场景,为企业构建实时、高效、可扩展的数据仓库解决方案。以下是对AnalyticDB产品使用合集的概述,包括数据导入、查询分析、数据管理、运维监控、扩展功能等方面。
|
机器学习/深度学习 JSON JavaScript
LangChain-21 Text Splitters 内容切分器 支持多种格式 HTML JSON md Code(JS/Py/TS/etc) 进行切分并输出 方便将数据进行结构化后检索
LangChain-21 Text Splitters 内容切分器 支持多种格式 HTML JSON md Code(JS/Py/TS/etc) 进行切分并输出 方便将数据进行结构化后检索
1009 0
|
SQL JSON 关系型数据库
MySQL 8.0.21 JSON_VALUE() 介绍
MySQL 8.0.21发布了,其中一个新特性是JSON_VALUE()函数。主要的动机是简化JSON数据的索引创建,但是还有更多的原因。
2533 0
|
JSON JavaScript API
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 错误分析
本文探讨了Python中处理JSON数据时遇到的`JSONDecodeError`,该错误通常由JSON格式错误或数据源问题引起。解决方法包括检查数据源、使用异常处理机制和调试日志记录。示例代码展示了如何从文件和API读取JSON并处理异常。注意事项涉及验证JSON规范、处理特殊字符和选择合适解析器。通过这些步骤,可以有效解决JSON解码错误,确保数据正确解析。
4216 0
|
SQL XML JSON
MySQL请求使用JSON索引查询数据量不准确
MySQL请求使用JSON索引查询数据量不准确