2016-07-30 8 views
0

Hallo Ich möchte von zwei Filter meine Graph Ergebnisse sortieren ..Conditional Order By-Klausel In Cypher Abfrage Neo4j

Meine Cypher Abfrage wie folgt aussieht ..

MATCH (n:User{user_id:304020})-[r:know]->(m:User) with m MATCH (m)-[s:like|create|share]->(o{is_active:1}) 

with m, s, o, (toInt(timestamp()/1000)-toInt(o.created_on))/86400 as days, 
(toInt(timestamp()/1000)-toInt(o.created_on))/3600 as hours, 
(1- round(o.impression_count_all/20)/50) as low_boost 

with m,s,o,days,low_boost,hours, 
       CASE 
        WHEN days > 30 THEN 0.05 
        WHEN days >=20 AND days <=30 THEN 0.1 
        WHEN days >=10 AND days <=20 THEN 0.2 
        WHEN days >=5 AND days <=10 THEN 0.4 
        WHEN days >=2 AND days <=5 THEN 0.5 
        WHEN days =1 THEN 0.6 
        WHEN days < 1 THEN 
        CASE 
         WHEN hours <= 2 THEN 1 
         WHEN hours > 2 AND hours <= 8 THEN 0.9 
         WHEN hours > 8 AND hours <= 16 THEN 0.8 
         WHEN hours > 16 AND hours < 23 THEN 0.75 
         WHEN hours >= 23 AND hours <= 24 THEN 0.7 
        END 
       END as rs, 

       CASE 
        WHEN low_boost > 0 THEN low_boost 
        WHEN low_boost <= 0 THEN 0 
       END as lb 
where has(o.trending_score_all) and has(o.impression_count_all) and not(o.is_featured=2) 

RETURN distinct o.story_id as story_id, 
(o.trending_score_all*4) as ts, (o.trending_score_all + rs + lb) as final_score, 
count(s) as rel_count,max(s.activity_id) as id, toInt(o.created_on) as created_on 

ORDER BY (CASE WHEN ts > 3 THEN final_score desc, rel_count desc ELSE ts) END) DESC 
skip 0 limit 10; 

Jetzt Wenn ts> 3, I wollen Ergebnisse nur von beiden final_score und rel_count ELSE srt von ts sortieren .. Bitte ändern, um durch ..

Antwort

0

1) Sie Paginierung verwenden (überspringen und Limit)

2) Wenn ich unde rstand, was Sie brauchen, fügen Sie dann „else“ zu sortieren:

UNWIND RANGE(1,100) as i 
WITH i, rand()*5 as x, toInt(rand()*10) as y 
RETURN i, x, y, CASE WHEN x>3 THEN 1 ELSE 0 END as for_sort 
    ORDER BY 
     CASE 
      WHEN for_sort=1 THEN x ELSE y END DESC, 
     CASE 
      WHEN for_sort=1 THEN y ELSE x END DESC 
+0

Ich habe meine Frage aktualisiert..Bitte schauen Sie sich das an. – JugalS

0

Enthält diese stark vereinfachte Abfrage (die ein einziges Argument verwendet für ORDER BY) für Sie arbeiten?

MATCH (u:User)-[r:like]->(s:Story) 
WITH s, (s.trending_score_all*4) AS ts 
RETURN DISTINCT s.story_id, ts, TOINT(s.impression_count_72) 
ORDER BY (CASE WHEN ts > 3 THEN ts ELSE TOINT(s.impression_count_72) END) DESC 
LIMIT 10; 

[EDITED]

Wenn Sie durch eine unterschiedliche Anzahl von Werten sortieren (je nach Situation) Sie haben eine Abhilfe zu verwenden, da Cypher nicht, dass direkt unterstützen.

Nehmen wir zum Beispiel an, wenn (ts> 3) möchten Sie bestellen, indem ts DESC und dann von s.story_id ASC. In dieser Situation könnte man die oben ORDER BY Klausel dies ändern:

ORDER BY 
    (CASE WHEN ts > 3 THEN ts ELSE TOINT(s.impression_count_72) END) DESC, 
    (CASE WHEN ts > 3 THEN s.story_id ELSE NULL END) ASC 

Durch die Verwendung von NULL (oder einen Literalwert) auf diese Weise, Sie eines des Untersort effektiv nichts zu tun haben können.

+0

Das good..I ist vergessen in einem Fall zu erwähnen, dass ich von zwei Feldern wie diese ORDER BY sortieren möchten (CASE WHEN ts> 3 THEN rel_count ab, final_score ab ELSE final_score END) DESC Unter der Annahme, ich bin verfügbar final_score und rel_count in der Abfrage .. – JugalS

+0

Ich habe meine Frage aktualisiert..Bitte schauen Sie sich das an. – JugalS

+0

Bitte sehen Sie meine bearbeitete Antwort. – cybersam