Как вернуть вершины из разных графов по одному запросу с помощью ApacheAGE?

Я хотел получить все вершины из двух разных графов, которые я создал (один называетсяfamily_treeа другойtaxonomy_biology) и использовал для этого следующую команду:

      SELECT * FROM cypher ('family_tree' AND 'taxonomy_biology', $$
MATCH (v)
RETURN v
$$) as (vertex agtype);

Но затем терминал возвращает эту ошибку:

      ERROR:  invalid input syntax for type boolean: "family_tree"
LINE 1: SELECT * FROM cypher('family_tree' AND 'taxonomy_biology', $...

Угадывая, как работает ApacheAGE, он просматривает все доступные графы и возвращаетtrueесли есть доступный граф с таким же именем илиfalseесли это не так. Тем не менее, передача двух графов, которые существуют, вызовет ошибку.

Кстати, ввод того же запроса, но для каждого графика, вернул это:

      SELECT * FROM cypher('taxonomy_biology', $$
MATCH (v)
RETURN v
$$) as (VERTEX agtype);
                                         vertex
-----------------------------------------------------------------------------------------
 {"id": 844424930131969, "label": "Kingdom", "properties": {"name": "Animalia"}}::vertex
 {"id": 1125899906842625, "label": "Phylum", "properties": {"name": "Cnidaria"}}::vertex
(2 rows)
      SELECT * FROM cypher('family_tree', $$                                                                                                                      MATCH (v)
RETURN v
$$) as (VERTEX agtype);
                                                                                                       vertex

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 {"id": 844424930131969, "label": "Person", "properties": {"name": "Louis", "titles": ["Emperor of the Carolingian Empire", "King of the Franks", "King of Aquitaine"], "year_born": 778, "year_died": 840}}::vertex
 {"id": 844424930131970, "label": "Person", "properties": {"name": "Hildegard", "titles": ["Frankish queen consort"], "year_born": 754, "year_died": 783}}::vertex
 {"id": 844424930131971, "label": "Person", "properties": {"name": "Charlemagne", "titles": ["Holy Roman Emperor", "King of the Franks", "King of the Lombards"], "year_born": 747, "year_died": 814}}::vertex
(3 rows)

Итак, как я могу вернуть вершины из обоих этих графов в одном запросе?

7 ответов

После того, как таблица возвращена из AGE, она аналогична любой таблице Postgress. Вы можете использовать все операции, доступные в Postgres, такие как «Join», «Union», «Intersect» и «Except». Официальный документ

Этот код подойдет для вашей цели.

      SELECT * FROM cypher ('family_tree', $$
    MATCH (v)
    RETURN v
$$) as (vertex agtype)
JOIN 
SELECT * FROM cypher ('taxonomy_biology', $$
    MATCH (v)
    RETURN v
$$) as (vertex agtype);

Согласно документации , вы можете запросить несколько графов, используя предложение JOIN. Например, вы можете вернуть вершины изfamily_treeиtaxonomy_biologyсо следующим запросом:

      SELECT family_tree, taxonomy_biology
FROM cypher('family_tree', $$
MATCH (v)
RETURN v
$$) as family_tree(vertex agtype)
JOIN cypher('taxonomy_biology', $$
MATCH (n)
RETURN n
$$) as taxonomy_biology(vertex agtype)
ON family_tree = taxonomy_biology;

Предложение UNION должно работать нормально, и другой альтернативой может быть использование предложения JOIN, как в примере в документации Apache.

В вашем случае код должен быть примерно таким, используя UNION:

      SELECT * 
FROM cypher ('family_tree', $$
    MATCH (v)
    RETURN v
$$) as (vertex agtype)
UNION 
SELECT * 
FROM cypher ('taxonomy_biology', $$
    MATCH (v)
    RETURN v
$$) as (vertex agtype);

Вы можете использовать предложение JOIN и прикрепить оба запроса, а в «ON» вы можете сделать 1 = 1 , поскольку мы не сравниваем конкретные вершины. Я покажу вам фрагмент, вы поймете лучше.

И еще одна вещь, которую вы можете сделать, это использовать предложение WITH следующим образом:

Но недостаток в том, что у вас будут повторяющиеся строки

Запрос возвращает ошибку, поскольку синтаксисcypher()функция не позволяет комбинировать два графика.

Чтобы запросить несколько графиков,JOINиONПредложения используются в соответствии с документацией AGE .

Нет, к сожалению, вы не можете использовать функцию шифрования для запроса нескольких графиков в одном запросе. Первым аргументом функции шифрования должно быть имя одного графа, а не список имен графов. Возможным решением, предложенным Wendel , было бы использованиеUNIONпункт.

Другой подход, который вы можете попробовать, — написать специальную функцию или хранимую процедуру, которая извлекает все вершины из обоих графов и возвращает их как единый набор результатов. Например:

      CREATE OR REPLACE FUNCTION get_all_vertices()
RETURNS TABLE(vertex agtype)
LANGUAGE plpgsql
AS $BODY$
BEGIN
    LOAD 'age';
    SET search_path TO ag_catalog;

    RETURN QUERY
        SELECT * FROM cypher('family_tree', $$ MATCH (n) RETURN n $$) as (n agtype)
        UNION
        SELECT * FROM cypher('taxonomy_biology', $$ MATCH (n) RETURN n $$) as (n agtype);
END
$BODY$;

После создания этой функции вы можете использовать ее в инструкции SELECT для получения всех вершин из обоих графов, используя:

      SELECT * FROM get_all_vertices();

Вы не можете делать запросы к двум графам, используя шифрованные запросы. Однако обычный запрос SQL обратится к этой документации для получения дополнительной информации.

Другие вопросы по тегам