你如何在 Postgres 的 plv8 函数中 return 行 JSON ?
How do you return rows of JSON in a plv8 function in Postgres?
我无法理解这个上下文。这是我使用一些内置函数的第一次尝试:
到目前为止我尝试了什么
SELECT json_build_object('id', MD5(c.id), 'firstName',
c.first_name, 'lastName', c.last_name, 'location',
json_build_object('city', cl.city, 'state', cl.state))
FROM person p
LEFT JOIN (SELECT id, city, state FROM
person_location) pl ON pl.id = p.id
LIMIT 10
对于这个小示例以及 returns 10 行来说效果很好。如果我取消限制,我将获得所有行。完美的;然而,这是为了支持将数据直接馈送到 Logstash 的视图,因此有一些自定义业务逻辑可以清理字段并执行其他一些轻任务。为了解决这个问题,尝试 plv8
是有意义的
plv8方法:
CREATE OR REPLACE FUNCTION generate_search_documents()
RETURNS SETOF person_test AS
$$
const _ = require('lodash'),
candidates = plv8.execute('select * FROM candidate LIMIT 10');
plv8.return_next(people);
$$
LANGUAGE plv8;
我已经迷路了。我正在尝试做的是 select 我需要的 table 正确连接,清理数据,并构建我的 JSON 对象和 return 对象每行。在第一种方法中,很明显在查询中我是在一个人的上下文中工作。在下面的方法中,我似乎正在执行 select 我们 table 中所有 8000 万人的查询。这并不容易。
知道如何使用此方法来复制我在第一个示例中尝试做的事情吗?
示例table:
create table person(id int primary key, first_name text, last_name text);
insert into person values
(1, 'John', 'Smith'),
(2, 'Phil', 'Jones');
select
json_build_object(
'id', id,
'firstname', first_name,
'lastname', last_name)
from person;
json_build_object
--------------------------------------------------------
{"id" : 1, "firstname" : "John", "lastname" : "Smith"}
{"id" : 2, "firstname" : "Phil", "lastname" : "Jones"}
(2 rows)
如何将函数中的行和 return 连续行修改为 json?
您应该将 setof jsonb
(或 setof json
)声明为 return 类型的函数。更新值并在循环中使用 plv8.return_next()
,示例:
create or replace function person_as_jsonb()
returns setof jsonb language plv8 as $$
var persons = plv8.execute('select * from person');
var len = persons.length;
for (var i = 0; i < len; i++) {
persons[i].first_name = persons[i].first_name + '?';
persons[i].last_name = persons[i].last_name + '!';
plv8.return_next(persons[i]);
}
$$;
select *
from person_as_jsonb();
person_as_json
---------------------------------------------------------
{"id": 1, "last_name": "Smith!", "first_name": "John?"}
{"id": 2, "last_name": "Jones!", "first_name": "Phil?"}
(2 rows)
以上函数适用于非常有限的数据集。甚至不要对一百万行或更多行的整个 table 进行尝试。
但是,您可以编写修改单行的函数。 plv8 足够聪明,可以理解何时声明参数的自定义类型(在本例中为 table 名称)并将其用作函数内部的 json (jsonb),示例:
create or replace function modify_person(person person)
returns jsonb language plv8 as $$
person.first_name = person.first_name+ '??';
person.last_name = person.last_name+ '!!';
return person;
$$;
在 select 查询中使用它(Postgres 本身 在这里创建一个循环 ,该函数分别为每一行调用):
select modify_person(person)
from person;
modify_person
-----------------------------------------------------------
{"id": 1, "last_name": "Smith!!", "first_name": "John??"}
{"id": 2, "last_name": "Jones!!", "first_name": "Phil??"}
(2 rows)
请注意,您只能更改 return 类型以获得类型化记录的结果(在这种情况下,您应该在 from 子句中调用函数):
create or replace function modify_person_row(person person)
returns person language plv8 as $$
person.first_name = person.first_name+ '??';
person.last_name = person.last_name+ '!!';
return person;
$$;
select modified.*
from person,
lateral modify_person_row(person) modified
id | first_name | last_name
----+------------+-----------
1 | John?? | Smith!!
2 | Phil?? | Jones!!
(2 rows)
我无法理解这个上下文。这是我使用一些内置函数的第一次尝试:
到目前为止我尝试了什么
SELECT json_build_object('id', MD5(c.id), 'firstName',
c.first_name, 'lastName', c.last_name, 'location',
json_build_object('city', cl.city, 'state', cl.state))
FROM person p
LEFT JOIN (SELECT id, city, state FROM
person_location) pl ON pl.id = p.id
LIMIT 10
对于这个小示例以及 returns 10 行来说效果很好。如果我取消限制,我将获得所有行。完美的;然而,这是为了支持将数据直接馈送到 Logstash 的视图,因此有一些自定义业务逻辑可以清理字段并执行其他一些轻任务。为了解决这个问题,尝试 plv8
是有意义的plv8方法:
CREATE OR REPLACE FUNCTION generate_search_documents()
RETURNS SETOF person_test AS
$$
const _ = require('lodash'),
candidates = plv8.execute('select * FROM candidate LIMIT 10');
plv8.return_next(people);
$$
LANGUAGE plv8;
我已经迷路了。我正在尝试做的是 select 我需要的 table 正确连接,清理数据,并构建我的 JSON 对象和 return 对象每行。在第一种方法中,很明显在查询中我是在一个人的上下文中工作。在下面的方法中,我似乎正在执行 select 我们 table 中所有 8000 万人的查询。这并不容易。
知道如何使用此方法来复制我在第一个示例中尝试做的事情吗?
示例table:
create table person(id int primary key, first_name text, last_name text);
insert into person values
(1, 'John', 'Smith'),
(2, 'Phil', 'Jones');
select
json_build_object(
'id', id,
'firstname', first_name,
'lastname', last_name)
from person;
json_build_object
--------------------------------------------------------
{"id" : 1, "firstname" : "John", "lastname" : "Smith"}
{"id" : 2, "firstname" : "Phil", "lastname" : "Jones"}
(2 rows)
如何将函数中的行和 return 连续行修改为 json?
您应该将 setof jsonb
(或 setof json
)声明为 return 类型的函数。更新值并在循环中使用 plv8.return_next()
,示例:
create or replace function person_as_jsonb()
returns setof jsonb language plv8 as $$
var persons = plv8.execute('select * from person');
var len = persons.length;
for (var i = 0; i < len; i++) {
persons[i].first_name = persons[i].first_name + '?';
persons[i].last_name = persons[i].last_name + '!';
plv8.return_next(persons[i]);
}
$$;
select *
from person_as_jsonb();
person_as_json
---------------------------------------------------------
{"id": 1, "last_name": "Smith!", "first_name": "John?"}
{"id": 2, "last_name": "Jones!", "first_name": "Phil?"}
(2 rows)
以上函数适用于非常有限的数据集。甚至不要对一百万行或更多行的整个 table 进行尝试。
但是,您可以编写修改单行的函数。 plv8 足够聪明,可以理解何时声明参数的自定义类型(在本例中为 table 名称)并将其用作函数内部的 json (jsonb),示例:
create or replace function modify_person(person person)
returns jsonb language plv8 as $$
person.first_name = person.first_name+ '??';
person.last_name = person.last_name+ '!!';
return person;
$$;
在 select 查询中使用它(Postgres 本身 在这里创建一个循环 ,该函数分别为每一行调用):
select modify_person(person)
from person;
modify_person
-----------------------------------------------------------
{"id": 1, "last_name": "Smith!!", "first_name": "John??"}
{"id": 2, "last_name": "Jones!!", "first_name": "Phil??"}
(2 rows)
请注意,您只能更改 return 类型以获得类型化记录的结果(在这种情况下,您应该在 from 子句中调用函数):
create or replace function modify_person_row(person person)
returns person language plv8 as $$
person.first_name = person.first_name+ '??';
person.last_name = person.last_name+ '!!';
return person;
$$;
select modified.*
from person,
lateral modify_person_row(person) modified
id | first_name | last_name
----+------------+-----------
1 | John?? | Smith!!
2 | Phil?? | Jones!!
(2 rows)