相关疑难解决方法(0)

在Rails和PostgreSQL中完全忽略时区

我正在处理Rails和Postgres中的日期和时间并遇到这个问题:

数据库采用UTC格式.

用户在Rails应用程序中设置选择的时区,但仅在获取用户本地时间来比较时间时使用.

用户存储时间,例如2012年3月17日晚上7点.我不希望存储时区转换或时区.我只想保存日期和时间.这样,如果用户改变他们的时区,它仍将显示2012年3月17日,晚上7点.

我只使用用户指定的时区来获取用户本地时区当前时间之前或之后的记录.

我目前正在使用"没有时区的时间戳",但是当我检索记录时,rails(?)会将它们转换为应用程序中的时区,这是我不想要的.

Appointment.first.time
 => Fri, 02 Mar 2012 19:00:00 UTC +00:00 
Run Code Online (Sandbox Code Playgroud)

因为数据库中的记录似乎是以UTC形式出现的,我的黑客是用当前时间,用'Date.strptime(str,"%m /%d /%Y")删除时区,然后做我的查询:

.where("time >= ?", date_start)
Run Code Online (Sandbox Code Playgroud)

似乎必须有一种更简单的方法来忽略周围的时区.有任何想法吗?

postgresql timezone datetime ruby-on-rails ruby-on-rails-3

156
推荐指数
1
解决办法
3万
查看次数

用于在JSON数组中查找元素的索引

我有一个看起来像这样的表:

CREATE TABLE tracks (id SERIAL, artists JSON);

INSERT INTO tracks (id, artists) 
  VALUES (1, '[{"name": "blink-182"}]');

INSERT INTO tracks (id, artists) 
  VALUES (2, '[{"name": "The Dirty Heads"}, {"name": "Louis Richards"}]');
Run Code Online (Sandbox Code Playgroud)

还有其他几个与此问题无关的列.将它们存储为JSON是有原因的.

我要做的是查找具有特定艺术家姓名(完全匹配)的曲目.

我正在使用此查询:

SELECT * FROM tracks 
  WHERE 'ARTIST NAME' IN
    (SELECT value->>'name' FROM json_array_elements(artists))
Run Code Online (Sandbox Code Playgroud)

例如

SELECT * FROM tracks
  WHERE 'The Dirty Heads' IN 
    (SELECT value->>'name' FROM json_array_elements(artists))
Run Code Online (Sandbox Code Playgroud)

但是,这会进行全表扫描,并且速度不是很快.我尝试使用函数创建GIN索引names_as_array(artists)并使用'ARTIST NAME' = ANY names_as_array(artists),但是不使用索引并且查询实际上明显更慢.

sql postgresql indexing json jsonb

74
推荐指数
1
解决办法
5万
查看次数

带有元素编号的PostgreSQL unnest()

当我有一个具有分隔值的列时,我可以使用该unnest()函数:

myTable
id | elements
---+------------
1  |ab,cd,efg,hi
2  |jk,lm,no,pq
3  |rstuv,wxyz

select id, unnest(string_to_array(elements, ',')) AS elem
from myTable

id | elem
---+-----
1  | ab
1  | cd
1  | efg
1  | hi
2  | jk
...
Run Code Online (Sandbox Code Playgroud)

我如何包含元素编号?即:

id | elem | nr
---+------+---
1  | ab   | 1
1  | cd   | 2
1  | efg  | 3
1  | hi   | 4
2  | jk   | 1
...
Run Code Online (Sandbox Code Playgroud)

我想要源字符串中每个元素的原始位置.我试着窗口函数(row_number(), …

sql arrays postgresql window-functions set-returning-functions

69
推荐指数
3
解决办法
8万
查看次数

JSON上的PostgreSQL索引

使用Postgres 9.4,我想在json列上创建一个索引,该索引将在搜索列中的特定键时使用.

例如,我有一个带有json列'animals'的'farm'表.

animals列具有一般格式的json对象:

'{"cow": 2, "chicken": 11, "horse": 3}'
Run Code Online (Sandbox Code Playgroud)

我已经尝试了许多索引(单独):

(1) create INDEX animal_index ON farm ((animal ->> 'cow'));
(2) create INDEX animal_index ON farm using gin ((animal ->> 'cow'));
(3) create INDEX animal_index ON farm using gist ((animal ->> 'cow'));
Run Code Online (Sandbox Code Playgroud)

我想运行如下查询:

SELECT * FROM farm WHERE (animal ->> 'cow') > 3;
Run Code Online (Sandbox Code Playgroud)

并让该查询使用索引.

当我运行此查询时:

SELECT * FROM farm WHERE (animal ->> 'cow') is null;
Run Code Online (Sandbox Code Playgroud)

然后(1)索引起作用,但我不能让任何索引适用于不等式.

这样的指数可能吗?

农场表只包含约5000个农场,但其中一些包含100个动物,查询对我的用例来说只需要太长时间.像这样的索引是我能想到的加速查询的唯一方法,但也许还有另一种选择.

postgresql json

34
推荐指数
1
解决办法
3万
查看次数

如何将PostgreSQL 9.4的jsonb类型转换为float

我正在尝试以下查询:

SELECT (json_data->'position'->'lat') + 1.0 AS lat FROM updates LIMIT 5;
Run Code Online (Sandbox Code Playgroud)

(+ 1.0只是强制转换为浮点数.我的实际查询要复杂得多,这个查询只是问题的一个测试用例.)

我收到错误:

ERROR:  operator does not exist: jsonb + numeric
Run Code Online (Sandbox Code Playgroud)

如果我添加显式转换:

SELECT (json_data->'position'->'lat')::float + 1.0 AS lat FROM updates LIMIT 5;
Run Code Online (Sandbox Code Playgroud)

错误变成:

ERROR:  operator does not exist: jsonb + double precesion
Run Code Online (Sandbox Code Playgroud)

我知道大多数jsonb值都不能转换成浮点数,但在这种情况下我知道lats都是JSON数.

是否有一个函数将jsonb值转换为浮点数(或为uncastable返回NULL)?

sql postgresql casting jsonb postgresql-9.4

33
推荐指数
5
解决办法
4万
查看次数

按JSON数组中的匹配数查询和排序

jsonb在Postgres 9.4和Rails 的列中使用JSON数组,我可以设置一个范围,返回包含传递给范围方法的数组中的任何元素的所有行- 如下所示:

scope :tagged, ->(tags) {
  where(["data->'tags' ?| ARRAY[:tags]", { tags: tags }])
}
Run Code Online (Sandbox Code Playgroud)

我还想根据数组中匹配元素的数量来排序结果.

我很欣赏我可能需要超出ActiveRecord的范围才能做到这一点,所以一个vanilla Postgres SQL的答案也很有帮助,但如果它可以包含在ActiveRecord中,那么它可以是一个可链的范围.

根据要求,这是一个示例表.(实际架构要复杂得多,但这就是我所关心的.)

 id |               data                
----+-----------------------------------
  1 | {"tags": ["foo", "bar", "baz"]}
  2 | {"tags": ["bish", "bash", "baz"]}
  3 |
  4 | {"tags": ["foo", "foo", "foo"]}
Run Code Online (Sandbox Code Playgroud)

用例是基于标签查找相关内容.更多匹配标签更相关,因此结果应按匹配数量排序.在Ruby中,我有一个这样的简单方法:

Page.tagged(['foo', 'bish', 'bash', 'baz']).all
Run Code Online (Sandbox Code Playgroud)

哪个应按以下顺序返回页面:2, 1, 4.

postgresql activerecord ruby-on-rails ruby-on-rails-4 postgresql-9.4

12
推荐指数
1
解决办法
1343
查看次数

jsonb键/值上的模式匹配

我正在使用PostgreSQL 9.4.我的表有一jsonb栏:

CREATE TABLE "PreStage".transaction (
  transaction_id serial NOT NULL,
  transaction jsonb
  CONSTRAINT pk_transaction PRIMARY KEY (transaction_id)
);

CREATE INDEX idxgin ON "PreStage".transaction USING gin (transaction);
Run Code Online (Sandbox Code Playgroud)

我在JSONB列中按键/值存储事务.其中一个要求是从键值中搜索客户名称,因此我运行的查询如下:

SELECT transaction as data FROM "PreStage".transaction
WHERE  transaction->>('HCP_FST_NM') ilike ('%neer%');
Run Code Online (Sandbox Code Playgroud)

我做什么似乎查询不喜欢GIN索引.如何使查询使用不区分大小写模式搜索的GIN索引?

我尝试将jsonb列更改为文本,使用gin_trgm_ops搜索所需文本对其进行索引,然后将结果转换为json然后搜索所需的键/值.这种方法似乎不起作用.

postgresql indexing json gwt-gin jsonb

4
推荐指数
1
解决办法
1997
查看次数

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

这是对jsonb键/值的模式匹配的后续跟进

我有一张桌子如下

CREATE TABLE "PreStage".transaction (
  transaction_id serial NOT NULL,
  transaction jsonb
  CONSTRAINT pk_transaction PRIMARY KEY (transaction_id)
);
Run Code Online (Sandbox Code Playgroud)

我的事务jsonb列中的内容看起来像

{"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": ""}
Run Code Online (Sandbox Code Playgroud)

我需要搜索查询,如:

SELECT transaction AS data FROM   "PreStage".transaction
WHERE  transaction->>'HCP_FST_NM' ILIKE '%neer%';
Run Code Online (Sandbox Code Playgroud)

但我需要让我的用户灵活地搜索任何键/值.

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

CREATE INDEX idxgin ON "PreStage".transaction
USING gin ((transaction->>'HCP_FST_NM') gin_trgm_ops);
Run Code Online (Sandbox Code Playgroud)

哪个有效,但我也想索引其他键.因此尝试了类似的事情:

CREATE INDEX idxgin ON "PreStage".transaction USING gin …
Run Code Online (Sandbox Code Playgroud)

postgresql indexing pattern-matching jsonb

4
推荐指数
2
解决办法
2053
查看次数