构建复杂的输出并对Neo4j中的记录进行排名

时间:2019-06-25 18:22:24

标签: neo4j cypher neo4j-apoc

此问题与上一篇文章直接相关:

How to calculate rank for float values in Neo4j?

我正在尝试将“等级”和“权重”值与原点和路径合并。我可以成功完成此操作:

CALL 
 apoc.load.json("file:///.../input.json") YIELD value 
 UNWIND value.origin AS orig 
 MATCH(origin:concept{name:orig.label}) WITH value, collect(origin) as 
 origins 
 UNWIND value.target AS tar MATCH(target:concept{name:tar.label}) 
 UNWIND origins AS origin WITH origin, target 
 CALL apoc.algo.dijkstra(origin, target, 'link', 'Weight') yield path as 
 path, weight as weight 
 WITH origin, path, weight ORDER BY weight ASC WITH {origin: origin, weight: 
 collect(weight)} AS SuggestionForOrigin UNWIND [r in range(1, 
 SIZE(SuggestionForOrigin.weight)) | {origin: SuggestionForOrigin.origin, 
 rank:r, weight: SuggestionForOrigin.weight[r-1]}] AS suggestion RETURN 
 suggestion

然后我得到以下结果(这对我来说很令人满意):

{"origin": {"name": "A","type": "string"},"rank": 1,"weight": 0.0}
 {"origin": {"name": "A","type": "string"},"rank": 2,"weight": 
 0.6180339887498948}
 {"origin": {"name": "P1","type": "string"},"rank": 1,"weight": 
 0.6180339887498948}
 {"origin": {"name": "P1","type": "string"},"rank": 2,"weight": 
 1.2360679774997896}

但是当我尝试合并“ path”参数时,我遇到了麻烦。我认为,我过度补偿了这些东西。我想实现的目标是(不完全是,但是能够将“路径”与适当的“重量”结合起来):

{"origin": {....}, "path": {...}, "rank": 1,"weight": 0.0}

这需要与特定的起点节点相关,如果我对第一个起点有3条路径建议,则需要将它们组合在一起。我已经尝试过,但是无法按我的意愿进行操作:

...
 CALL apoc.algo.dijkstra(origin, target, 'link', 'Weight') yield path as 
 path, weight 
 WITH {origin: origin, path: collect(path), weight: collect(weight)} AS 
 SuggestionForOrigin 
 UNWIND [r in range(1, SIZE(SuggestionForOrigin.weight)) | {rank:r, weight: 
 SuggestionForOrigin.weight[r-1], path: SuggestionForOrigin}] AS suggestion 
 WITH {origin: SuggestionForOrigin.origin, suggestions: collect(suggestion) 
 [0..3]} AS output 
 RETURN output

如果您能提供帮助,我将不胜感激。

1 个答案:

答案 0 :(得分:1)

这应该有效:

before insert or update of rent_date, return_date on rent
for each row
declare

pragma AUTONOMOUS_TRANSACTION;

v_rentDate date;
v_returnDate date;


begin
 select rent_date 
   into v_rentDate
   from rent
  where rent_date = :new.rent_date;


  select return_date
    into v_returnDate
    from rent
   where return_date = :new.return_date;


if v_returnDate < v_rentDate then
  raise_application_error(-20158, 'Return date must be after the rent date');
else
  dbms_output.put_line('TEST');
end if;

  exception when no_data_found then raise_application_error(-20157, 'No data found');

end;
/


insert into rent values (82,sysdate-5,101,sysdate,sysdate+5,100);
--0 rows inserted