2014-10-16 3 views
2

Я создал простой график, используя следующие данные:Neo4j остальные апи высчитывать появляется вернуть декартово произведение узлов

CREATE (england:Country {Name:"England",Id:1}) 
CREATE CONSTRAINT ON (c:Country) ASSERT c.ID IS UNIQUE 

CREATE (john:King {Name:"John",Id:1}) 
CREATE (henry3:King {Name:"Henry III",Id:2}) 
CREATE (edward1:King {Name:"Edward I",Id:3}) 
CREATE CONSTRAINT ON (k:King) ASSERT k.ID IS UNIQUE 
MATCH (country:Country),(king:King) WHERE country.Id = 1 AND king.Id = 1 CREATE (country)<-[r:KING_OF]-(king) 
MATCH (country:Country),(king:King) WHERE country.Id = 1 AND king.Id = 2 CREATE (country)<-[r:KING_OF]-(king) 
MATCH (country:Country),(king:King) WHERE country.Id = 1 AND king.Id = 3 CREATE (country)<-[r:KING_OF]-(king) 

CREATE (cornwall:County {Name:"Cornwall",Id:1}) 
CREATE (devon:County {Name:"Devon",Id:2}) 
CREATE (somerset:County {Name:"Somerset",Id:3}) 
CREATE CONSTRAINT ON (c:County) ASSERT c.ID IS UNIQUE 
MATCH (country:Country),(county:County) WHERE country.Id = 1 AND county.Id = 1 CREATE (country)<-[r:COUNTY_IN]-(county) 
MATCH (country:Country),(county:County) WHERE country.Id = 1 AND county.Id = 2 CREATE (country)<-[r:COUNTY_IN]-(county) 
MATCH (country:Country),(county:County) WHERE country.Id = 1 AND county.Id = 3 CREATE (country)<-[r:COUNTY_IN]-(county) 

CREATE (bristol:City {Name:"Bristol",Id:1}) 
CREATE (london:City {Name:"London",Id:2}) 
CREATE (york:City {Name:"York",Id:3}) 
CREATE CONSTRAINT ON (c:City) ASSERT c.ID IS UNIQUE 
MATCH (country:Country),(city:City) WHERE country.Id = 1 AND city.Id = 1 CREATE (country)<-[r:CITY_IN]-(city) 
MATCH (country:Country),(city:City) WHERE country.Id = 1 AND city.Id = 2 CREATE (country)<-[r:CITY_IN]-(city) 
MATCH (country:Country),(city:City) WHERE country.Id = 1 AND city.Id = 3 CREATE (country)<-[r:CITY_IN]-(city) 

(Обратите внимание, что я использую «thiscomputer.mydomain.com» в качестве псевдонима для ' локальный», который так смешно прутки меня от использования) ...

Если я иду в http://thiscomputer.mydomain.com:7474/browser/ и выполнить высчитывать

MATCH cities = (city:City)-[]->(c:Country {Id:1}), counties = (county:County)-[]->(c:Country {Id:1}), kings = (king:King)-[]->(c:Country {Id:1}) RETURN cities, counties, kings 

... Я получаю хороший график, сосредоточенный вокруг страны Англия. Никакие узлы не повторяются.

Если я вспылить клиента REST и выполнить следующие действия:

URL: http://thiscomputer.mydomain.com:7474/db/data/transaction/commit Глагол: POST тела:

{ 
    "statements" : [{ 
"statement": "MATCH cities = (city:City)-[]->(c:Country {Id:1}), counties = (county:County)-[]->(c:Country {Id:1}), kings = (king:King)-[]->(c:Country {Id:1}) RETURN cities, counties, kings", 
"resultDataContents" : [ "graph" ] 
}] 
} 

(Обратите внимание, что высчитывать запрос идентичен)

Я получаю набор результатов, которые слишком велики для вставки здесь.

В принципе, я, кажется, получаю декартово произведение результатов. Поскольку есть 3 короля, 3 округа и 3 города, есть 27 результатов.

Это довольно простой график. В домене, в котором я работаю, график, который я хочу, будет содержать совокупный корень (в данном примере, Англия) и множество связанных узлов разных типов. Если REST API вернул декартовую продукцию, я мог бы получить много тысяч результатов.

Итак, мой вопрос заключается в следующем: почему REST API возвращает декартово произведение всех возвращенных узлов? Является ли мой cypher некорректным, или я неправильно использую REST API?

Было бы намного проще, если бы я мог получить результаты, как это (псевдо-JSON):

{ 
    Country:{ 
    Name: "England", 
    Id: 1, 
    Cities:[ 
     ...etc 
    ], 
    Counties:[ 
     ...etc 
    ], 
    Kings:[ 
     ...etc 
    ] 
    } 
} 

или, возможно, даже это:

{ 
    data:{ 
    nodes:[ 
     { 
     Name:"England", 
     Id: 1, 
     uniqueIdInResults:1 
     }, 
     ...etc 
    ], 
    relationships:[ 
     uniqueIdInResults1: 1, 
     uniqueIdInResults2: 2, 
     type: "KING_OF" 
    ] 
    } 
} 

Короче говоря, я думаю, denormalising данные в такие результаты могут быстро привести к слишком большому отклику. Есть ли способ структурировать шифр или вызов API REST для получения результатов с меньшим количеством повторений?

+2

Хорошая точка в улучшении формата ответа для варианта «graph», так как его не нужно разделять на строки, но, возможно, это даже отдельный прецедент. Один с каждой строкой и один с возвращенным глобальным графом. –

+0

Что мне интересно делать, это загрузка всего совокупности (в смысле DDD) с помощью одного вызова.В то время как я предполагаю, что это должно быть возможным (один поиск индекса для получения совокупного корня, а затем чистый обход графика), я думаю, что денормализация делает объем данных непрактичным. – David

+0

Я понимаю, что существуют проблемы, связанные с тем, как вы представляете многоиерархические данные, используя (например) JSON, но мое второе предложение (возврат списка узлов и список отношений) было бы одним подходом и гораздо более эффективным, чем декартово произведение. – David

ответ

3

Запрос, который вы используете в браузере, абсолютно возвращает также декартово произведение - он просто не появляется таким образом, потому что визуальный результат будет показывать только узлы один раз.

Выполните следующее в браузере. Вы увидите довольно быстро все совпадения, которые вы получаете.

MATCH cities = (city:City)-[]->(c:Country {Id:1}), 
     counties = (county:County)-[]->(c:Country {Id:1}), 
     kings = (king:King)-[]->(c:Country {Id:1}) 
RETURN EXTRACT(x IN NODES(cities) | x.Name), 
     EXTRACT(x IN NODES(counties) |x.Name), 
     EXTRACT(x IN NODES(kings) | x.Name) 

Как и ожидалось, я получаю декартово произведение 27 строк.

+0

Спасибо. Дело не в том, что я думал, что это REST API (в отличие от cypher), делающий денормализацию. Я просто хотел бы знать, могу ли я как-то уговорить запрос к более эффективному формированию ответов. – David

+1

Я предполагаю, что я имел в виду «... я получаю хороший график, ориентированный на всю страну Англии. Никаких узлов не повторяют». Я хочу сказать, что визуальный результат может вводить в заблуждение с точки зрения избыточных данных/декартовых произведений. –

+1

Но у меня мало опыта использования результата «graph» в REST, поэтому я не уверен, что мне будет очень помогать в редактировании Cypher, чтобы получить именно то, что вы хотите. –

Смежные вопросы