2016-04-21 3 views
0

Я хотел бы увеличить границы для пользователя в зависимости от некоторой базы правил обхода графика. В основном в MySQL я хотел бы сделать что:cypher union group by sum

select id, sum(weight) as total 
from 
(
    select id, 10 as weight 
    from user 
    inner join userRel1 ON user.id = userRel1.userId 
    where userRel1.attr1 in (1, 2) 
    union 
    select id, 5 as weight 
    from user 
    inner join userRel2 ON user.id = userRel2.userId 
    inner join userRel3 ON user.id = userRel3.userId 
    where userRel2.attr2 = 'a' and userRel3.attr2 = 'z' 
    union 
    ... 
) 
group by id 
order by total desc 

Кроме того, я уже writed этот запрос с некоторой помощью в гном 3, но я хотел бы сравнить производительность с шифром. Но я читал в этом post, что группа по объединению пока не представляется возможной, это означает, что cypher менее эффективен, чем гремлин? Должен ли я установить вес как свойства по краям, чтобы достичь этого?

Благодаря

ответ

0

Хотя это правда, что пост- UNION обработка still an open feature request, вам не нужно использовать UNION выполнить свой вариант использования.

Этот запрос должен сделать эквивалент вашего SQL (без учета неполной части):

WITH [] AS res 

OPTIONAL MATCH (user1:User), (userRel1:UserRel1) 
WHERE user1.id = userRel1.userId AND userRel1.attr1 IN [1, 2] 
WITH res, (CASE WHEN userRel1 IS NOT NULL THEN COLLECT({id: user1.id, weight: 10}) ELSE [] END) AS data 
WITH res + data AS res 

OPTIONAL MATCH (user2:User), (userRel2:UserRel2) 
WHERE user2.id = userRel2.userId AND userRel2.attr2 = 'a' 
OPTIONAL MATCH (userRel3:UserRel3) 
WHERE user2.id = userRel3.userId AND userRel3.attr2 = 'z' 
WITH res, (CASE WHEN userRel3 IS NOT NULL THEN COLLECT({id: user2.id, weight: 5}) ELSE [] END) AS data 
WITH res + data AS res 

UNWIND res AS result 
RETURN result.id, SUM(result.weight) AS weight; 

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

Запрос продолжает расширять (и заменяет) коллекцию res соответствующими парами id/weight, а затем объединяет их в конце.

блок с 2 OPTIONAL MATCH статей могли бы быть написаны с использованием одного OPTIONAL MATCH, но я думал, что это было более производительным делать ту же работу по частям, и чтобы отказ одного OPTIONAL MATCH к потенциально информировать Cypher даже не беспокоить с другой. Второй пункт блока WHERE основывается на узле user2, который найден первым OPTIONAL MATCH. user2 будет иметь значение NULL, если первый OPTIONAL MATCH не выполнен, и такое значение NULL также приведет к сбою второго предложения WHERE (что в свою очередь составит userRel3NULL).

+0

спасибо, что это работает. Я открыл новый пост более общий с проблемой производительности neo4j на основе такого запроса: http://stackoverflow.com/questions/36789389/mysql-vs-cypher-vs-gremlin-on-union-query – jrweb247

+0

Отлично. Не забудьте также перенести ответы, которые вы принимаете. – cybersam