Postgres 等效于 mongodb 的 facet 查询

Postgres equivalent of mongodb’s facet query

提问人:gopeeey 提问时间:11/16/2023 更新时间:11/17/2023 访问量:45

问:

Postgres中是否有办法实现与mongodb中的$facet查询相同的功能?也就是说,从查询结果创建分叉,并在这些单独的分叉中运行不同的操作。

所以假设我有一个“商店”表。我如何编写一个查询,首先根据一些一般标准过滤掉商店,假设我们只想要打开的商店(假设商店表上有一个带有布尔值的打开列)。然后从这个结果返回两个部分/组的商店。

第一部分是“最受欢迎”。它仅包含初始结果中 popularityCount(stores 表上的整数)大于 5 的商店,并且按 popularityCount 排序。第二部分是“新添加的”。这个仅包含过去 5 天内添加的初始结果中的存储,当然是按 createdDate 排序的。

因此,最终结果的 json 表示形式如下所示:

{
   "most popular": [{very old store}, {store a}, {store b}, {store c}],
   "newly added": [{store b}, {store a}, {store c}]
}
节点.js MongoDB PostgreSQL

评论

0赞 Zegarek 11/16/2023
听起来像一个聚合过滤子句(条件聚合)。

答:

2赞 Zegarek 11/16/2023 #1

为此,您可以使用常规聚合,在内部添加 order by 子句,在外部添加过滤器: db<>fiddle 上的演示:

select array_agg(stores order by popularity_count)
          filter(where popularity_count>5) 
          as "most popular"
      ,array_agg(stores order by created_date)
          filter(where now()-'5 days'::interval <= created_date) 
          as "newly added"
from stores where is_open;
最受欢迎 新增
{“(2,t,7,2023-10-02)”,“(3,t,8,2023-11-16)”,“(4,t,9,1970-01-01)”,“(9,t,99,2023-10-30)”,“(5,t,999,-无穷大)”} {“(1,t,2,2023-11-15)”,“(3,t,8,2023-11-16)”}

请注意,正和负是 PostgreSQL 中的有效日期时间戳infinity

使用 to_json(),您甚至可以获得您显示的确切 json 示例。下面我使用它的版本只是为了用 jsonb_pretty() 进行漂亮的打印:jsonbto_jsonb()

select jsonb_pretty(to_jsonb(payload)) 
from (
    select array_agg(stores order by popularity_count)
              filter(where popularity_count>5) 
              as "most popular"
          ,array_agg(stores order by created_date)
              filter(where now()-'5 days'::interval <= created_date) 
              as "newly added"
    from stores where is_open
) AS payload;
jsonb_pretty
{
“新增”: [ { “id”: 1, “is_open”: true, “created_date”: “2023-11-15”, “popularity_count”: 2 }, { “id”: 3, “is_open”: true, “created_date”: “2023-11-16”, “popularity_count”: 8
} ], “最受欢迎”: [

{ “id”: 2, “is_open”: true,

“created_date”:
“2023-10-02”,












“popularity_count”: 7 }, { “id”: 3, “is_open”: true, “created_date”: “2023-11-16”, “popularity_count”: 8 }, { “id”: 4, “is_open”: true, “created_date”: “1970-01-01”, “popularity_count”: 9


}, { “id”: 9, “is_open”: true,


“created_date”: “2023-10-30”,











“popularity_count”: 99 }, { “id”: 5, “is_open”: true, “created_date”: “-infinity”,




“popularity_count”: 999

}
]

}