在Postgres中有没有办法实现与MongoDB中的$Facet查询相同的功能?也就是说,从查询结果创建派生,并在这些单独的派生中运行不同的操作.

假设我有一个"store "表.我如何编写一个查询,首先,通过一些通用的标准过滤掉store ,比如我们只想要打开的store (让我们假设store 表上有一个布尔值的打开列).然后从这个结果返回两个存储区/组.

第一部分是"最受欢迎的".它只包含初始结果中PoparityCount(Stores表上的一个整数)大于5的存储,并按PoparityCount进行排序.第二部分会说"新增加的".它只包含在过go 5天内添加的初始结果中的存储,当然还按createdDate排序.

因此,最终结果的JSON表示如下所示:

{
   "most popular": [{very old store}, {store a}, {store b}, {store c}],
   "newly added": [{store b}, {store a}, {store c}]
}

推荐答案

Demo at db<>fiddle:

create table stores(id int,is_open boolean,popularity_count int,created_date date);
insert into stores values
(1,true,2,'yesterday'),
(2,true,7,now()-'1 month 2 weeks'::interval),
(3,true,8,'today allballs'),
(4,true,9,'epoch'),
(5,true,999,'-infinity'),
(6,false,0,'now'),
(7,false,0,'tomorrow'),
(8,false,0,'infinity'),
(9,true,99,'2023-10-30 13:13');

您可以使用常规聚合,在外部添加order by clause inside and a filter:

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;
most popular newly added
{"(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,-infinity)"} {"(1,t,2,2023-11-15)","(3,t,8,2023-11-16)"}

请注意,正infinity和负infinity在PostgreSQL中是valid date and timestamp.

使用to_json(),你甚至可以得到你所展示的json示例.下面我使用它的jsonb版本to_jsonb()只是为了用jsonb_pretty()漂亮地打印:

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
{
    "newly added": [
        {
            "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
        }
    ],
    "most popular": [
        {
            "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
        }
    ]
}

Node.js相关问答推荐

使用Google Cloud控制台时,onCall方法在云功能中失败

Mongoose-如何从父文档填充到子文档

MongoDB上的updateOne和findOneAndUpdate在Node.js中无法正常工作

try 使用Express和连接池将数据插入MySQL数据库时出现拒绝访问错误

条件内的表达式

如何从谷歌云中部署的应用程序连接到mongoDB Atlas?

使用 axios 和 Cheerio (Node js) 抓取 google 搜索

无法从 mongoDB 访问数据?

无法使用 Express 设置会话 cookie 的过期日期

在构建完成后,将AddedFiles文件夹的内容复制到dist文件夹

在路由上使用中间件时,Nodejs Express 应用程序失败

如何使用 NodeJS 加密模块将 ECDH 密钥转换为 PEM 格式

如果我使用像 express 这样的 node 服务器,是否需要 webpack-dev-server

gyp WARN EACCES 用户root没有访问开发目录的权限

在 Jade 包含中使用变量

从 zip 文件在 AWS 中创建 lambda 函数

安装Node.js 安装n 安装Node.js?

什么是 JavaScript 中的REPL?

要求('babel/register')不起作用

如何断言不为空?