如何使用 Jsonb 从给定日期检索消息?

How to retrieve messages from a given date using Jsonb?

我有以下 table:

CREATE TABLE tbl (tbl_id int, messages jsonb);
CREATE INDEX index_tbl ON tbl USING gin (messages);

并且 JSON 消息作为数组:

[{"user_id":1,"created_at":"2016-12-20","content":"Suspendisse accumsan tortor quis turpis. Sed ante."},
 {"user_id":2,"created_at":"2016-12-20","content":"Morbi sem mauris tibulum sagittis sapien."},
 {"user_id":1,"created_at":"2016-10-21","content":"In blandit ultrices enim. Phasellus id sapien in sapien iaculis congue."},
 {"user_id":3,"created_at":"2016-11-20","content":"Quisque ut erat. Curabitur gravida nisi at nibh. In hac habitasse platea dictumst."},
 {"user_id":4,"created_at":"2016-12-21","content":"Nunc rhoncus dui vel sem. Sed sagittis. ectus. Pellentesque at nulla. Suspendisse potenti. Cras in purus eu magna vulputate luctus."},
 {"user_id":6,"created_at":"2016-12-21","content":"Praesent id massa id nisl venenatis lacinia. iaculis congue."}]

怎样才能select用户一个月内的留言? 例如,12 月的用户仅 return 向我发送用户 2、4 和 6 的消息,因为用户 1 也在 11 月。

这return都是..

messages where the user is in only one month

WITH msg AS (
   SELECT tbl_id
        ,(msg->>'user_id')::int                                      AS user_id
        , date_trunc('month', (msg->>'created_at')::timestamp)::date AS created_month
        , msg->>'content'                                            AS content
   FROM   tbl t, jsonb_array_elements(t.messages) msg
   )
SELECT m.*
FROM  (
   SELECT user_id
   FROM   msg 
   GROUP  BY 1
   HAVING count(DISTINCT created_month) = 1
   ) u
JOIN msg m USING (user_id);
  1. jsonb_array_elements()解除JSON数组的嵌套。

  2. 提取相关键的值。只有日期的月份是相关的,使用 date_trunc() 并将结果转换回 date.

  3. 运行 由步骤 1.2.[ 产生的 CTE msg 上的实际查询。 =43=] 识别仅在一个月内发帖的用户 - 在整个 table 范围内,而不仅仅是在一行内。你没有澄清,我选择了这个解释。

  4. 自加入同一 CTE msg 到 return 标识用户的所有消息。

GIN 索引无济于事,因为您需要以任何一种方式检查每个数组元素。

开始时以规范化 table 存储消息对于您的查询来说会更简单、更快速:

message (user_id int, created_at date, content text)