Я новичок в Apache Age и postgres Json/Jsonb.
У меня есть граф, в котором вершины имеют многозначные свойства, каждое значение является объектом с фактическим значением свойства и тегами, как показано:
{
"id": "vertex1",
"propname": [
{
"value": "val1",
"tags": [
"T1",
"T2"
]
},
{
"value": "val2",
"tags": [
"T1",
"T3"
]
}
]
}
Я хотел бы получить все вершины, где проперти propname
имеет значение ‘val1’. Я не нашел, как это сделать в cypher. Я написал функцию, чтобы получить значение по заданному индексу, но это не цель, в конечном итоге я хотел бы иметь возможность написать оператор cypher, такой как
MATCH (n) WHERE property_has_value(n.propname, value) return n;
Я написал функцию, чтобы извлечь значение свойства по индексу.
CREATE OR REPLACE FUNCTION ag_catalog.property_value_at(agtype, text, int)
RETURNS agtype
LANGUAGE sql
IMMUTABLE
AS $function$
select agtype_object_field(agtype_array_element(agtype_object_field($1, $2), $3), '_value_')
$function$;
Таким образом, я могу писать запросы, такие как MATCH (n) WHERE property_value_at(propname, 0) = 'val1'
.
Но, как уже говорилось, это не цель, мне хотелось бы иметь возможность писать оператор cypher, такой как
MATCH (n) WHERE property_has_value(n.propname, value) return n;
Я предполагаю, что функции postgres JSON или JSONB могут помочь, но как я могу конвертировать из agtype в jsonb или json (я уже пробовал много вещей, таких как это
CREATE OR REPLACE FUNCTION property_value_count(agtype, text)
RETURNS integer
LANGUAGE sql
IMMUTABLE
AS $function$
select pg_catalog.json_array_length(to_jsonb(ag_catalog.agtype_object_field($1, $2)))
$function$;
но всегда получал следующую ошибку
ERROR: function pg_catalog.json_array_length(jsonb) does not exist
LINE 6: select pg_catalog.json_array_length(to_jsonb(ag_catal...
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
Есть ли какие-либо советы о том, как это сделать?
Большое спасибо, если вы сможете помочь.
Ответ
Чтобы получить все вершины графа, у которых многозначное свойство (например, propname
) содержит определенное значение (например, 'val1'
), вы можете использовать функциональность PostgreSQL для работы с JSONB. Давайте разберем, как это можно сделать в контексте Apache AGE и языка Cypher.
Шаг 1: Конверсия AGTYPE в JSONB
В библиотеке AG для PostgreSQL нет прямого способа преобразования типов agtype
в jsonb
, поэтому мы можем создать вспомогательную функцию, которая поможет выполнить это преобразование. Вот пример записи такой функции:
CREATE OR REPLACE FUNCTION agtype_to_jsonb(agtype)
RETURNS jsonb
LANGUAGE sql
IMMUTABLE
AS $function$
SELECT to_jsonb(agtype_object($1));
$function$;
Эта функция просто преобразует ваш agtype в jsonb, что позволит нам использовать все функции PostgreSQL для работы с jsonb.
Шаг 2: Функция для поиска значений
Теперь мы можем создать функцию, которая будет искать все значения val1
в свойстве propname
. Для этого нам понадобится следующая функция:
CREATE OR REPLACE FUNCTION property_has_value(agtype, text)
RETURNS boolean
LANGUAGE sql
IMMUTABLE
AS $function$
SELECT EXISTS (
SELECT 1
FROM jsonb_array_elements(agtype_to_jsonb($1)->'propname') AS elem
WHERE elem->>'value' = $2
);
$function$;
Эта функция проверяет, существует ли элемент в массиве propname
, у которого поле value
равно искомому значению.
Шаг 3: Использование Cypher для выполнения запроса
После того как мы создали функции, теперь мы можем использовать Cypher для поиска всех вершин:
MATCH (n)
WHERE property_has_value(n.propname, 'val1')
RETURN n;
Этот запрос найдет все вершины n
, у которых свойство propname
содержит значение val1
.
Заключение
Теперь у вас есть полное решение, которое позволяет находить вершины по значениям многозначных свойств. Используя функции PostgreSQL для работы с JSONB в совместимости с функциональностью Apache AGE, вы можете продолжать расширять функциональность ваших запросов. Если у вас есть дополнительные вопросы или вам нужно больше информации, не стесняйтесь спрашивать!