Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql 为模式匹配搜索索引jsonb数据_Postgresql_Indexing_Pattern Matching_Jsonb - Fatal编程技术网

Postgresql 为模式匹配搜索索引jsonb数据

Postgresql 为模式匹配搜索索引jsonb数据,postgresql,indexing,pattern-matching,jsonb,Postgresql,Indexing,Pattern Matching,Jsonb,这是对: 我有一张桌子如下 CREATE TABLE "PreStage".transaction ( transaction_id serial NOT NULL, transaction jsonb CONSTRAINT pk_transaction PRIMARY KEY (transaction_id) ); MyTransactionJSONB列中的内容如下所示 {"ADDR": "abcd", "CITY": "abcd", "PROV": "", "ADDR2":

这是对:

我有一张桌子如下

CREATE TABLE "PreStage".transaction (
  transaction_id serial NOT NULL,
  transaction jsonb
  CONSTRAINT pk_transaction PRIMARY KEY (transaction_id)
);
MyTransactionJSONB列中的内容如下所示

{"ADDR": "abcd", "CITY": "abcd", "PROV": "",
 "ADDR2": "",
 "ADDR3": "","CNSNT": "Research-NA", "CNTRY": "NL", "EMAIL": "@.com",
             "PHONE": "12345", "HCO_NM": "HELLO", "UNQ_ID": "", 
             "PSTL_CD": "1234", "HCP_SR_NM": "", "HCP_FST_NM": "",
             "HCP_MID_NM": ""}
我需要像这样的搜索查询:

SELECT transaction AS data FROM   "PreStage".transaction
WHERE  transaction->>'HCP_FST_NM' ILIKE '%neer%';
但我需要让我的用户灵活地动态搜索任何键/值

对上一个问题的回答建议将索引创建为:

CREATE INDEX idxgin ON "PreStage".transaction
USING gin ((transaction->>'HCP_FST_NM') gin_trgm_ops);
这是可行的,但我也想索引其他键。因此,我们尝试了以下方法:

CREATE INDEX idxgin ON "PreStage".transaction USING gin
((transaction->>'HCP_FST_NM'),(transaction->>'HCP_LST_NM') gin_trgm_ops) 
这不管用。这里最好的索引方法是什么,或者我必须为每个键创建一个单独的索引,在这种情况下,如果向数据中添加新的键/值对,该方法将不是通用的。

除了语法错误,
对于一些常用键(包含在许多行中和/或经常搜索)加上更多稀有键(包含在少数行中和/或很少搜索,新键可能会动态弹出)的组合,我建议使用以下组合:

常用键的三元索引 看起来您不会经常在一个搜索中组合多个键,一个包含多个键的索引会变得非常大和缓慢。因此,我将为每个常用键创建一个单独的索引。使其成为大多数行中不包含的键的部分索引:

CREATE INDEX trans_idxgin_HCP_FST_NM ON transaction  -- contained in most rows
USING gin ((transaction->>'HCP_FST_NM') gin_trgm_ops);

CREATE INDEX trans_idxgin_ADDR ON transaction  -- not in most rows
USING gin ((transaction->>'ADDR') gin_trgm_ops)
WHERE transaction ? 'ADDR';
如我之前的回答中所述:

基本jsonb GIN索引 如果您有许多不同的键和/或动态添加了新键,则可以使用基本(默认)
jsonb_ops
GIN索引覆盖其余键:

CREATE INDEX trans_idxgin ON "PreStage".transaction USING gin (transaction);
除此之外,它还支持搜索关键字。但不能将其用于值的模式匹配

查询 组合处理两个索引的谓词:

SELECT transaction AS data
FROM   "PreStage".transaction
WHERE  transaction->>'HCP_FST_NM' ILIKE '%neer%'
AND    transaction ? 'HCP_FST_NM';  -- even if that seems redundant.
第二个条件恰好也与我们的部分索引匹配

因此,或者给定的(常用/通用)键有一个特定的三元索引,或者至少有一个索引来查找(少数)包含稀有键的行,然后过滤匹配值。同一个查询应该能让您两全其美


请务必运行最新版本的Postgres,最近有各种成本估算更新。Postgres使用良好的估计和当前表统计信息来选择最佳查询计划是至关重要的。

没有内置索引可以精确地执行您想要的操作,搜索准确的键和相应的通配符匹配值,而不提前指定要使用的键。应该有可能创建一个扩展来实现这一点,但这将是一个非常多的工作,我不知道有任何存在

开箱即用的最佳选择可能是将jsonb强制转换为文本并为该文本编制索引:

create index on transaction using gin ((transaction::text) gin_trgm_ops);
然后向查询中添加第二个条件:

SELECT transaction AS data FROM transaction
WHERE  transaction->>'HCP_FST_NM' ILIKE '%neer%'
AND transaction::text ilike '%neer%';
现在,它可以使用索引查找任何包含“neer”的内容,然后重新检查“HCP_FST_NM”键的值中是否出现了“neer”,而不仅仅是
JSONB
中的其他位置

如果查询词出现在所需键的值以外的许多地方,那么这可能不会给您带来很好的性能。例如,如果有人搜索:

transaction->>'EMAIL' ilike '%ADDR%'
AND transaction::text ilike '%ADDR%';

索引将返回每一行,假设所有记录的结构都与您显示的相同,因为每一行都包含“ADDR”,因为它用作键。然后,每一行都会通过其他条件检查,但只有在做了大量工作之后。

在尝试使用如上所示的两个键创建索引时,我得到如下错误:数据类型文本没有访问方法gin的默认运算符类。您必须为索引指定运算符类或为数据类型定义默认运算符类。您需要为索引的两个部分指定gin_trgm_ops,而不仅仅是最后一部分。在讨论本主题时,它更适合于。再次感谢您。我们正在使用PostgreSQL 9.4。我们已经用PostgreSQL Json构建了一个动态框架。我们将看到在生产环境中一切都是如何运行的。对于使用jsquery for postgresql有何想法。似乎它可以使用GIN索引,但却提供了更多关于查询过滤器的选项。你对此有什么想法。