2016-03-09 3 views
0

У меня есть взвешенная Neo4j график книг предпочтений Алисы, Боб, Чарли и Дан:Ограничение числа друг-в-а-друг результатов в Cypher запроса

CREATE (alice:Person {name:'Alice'}) 
    CREATE (bob:Person {name: 'Bob'}) 
    CREATE (charlie:Person {name: 'Charlie'}) 
    CREATE (dan:Person {name: 'Dan'}) 
    CREATE (b00:Book {title:'Book 00'}) 
    CREATE (b01:Book {title:'Book 01'}) 
    CREATE (b02:Book {title:'Book 02'}) 
    CREATE (b03:Book {title:'Book 03'}) 
    CREATE (b04:Book {title:'Book 04'}) 
    CREATE (b05:Book {title:'Book 05'}) 
    CREATE (b06:Book {title:'Book 06'}) 
    CREATE (b07:Book {title:'Book 07'}) 
    CREATE (b08:Book {title:'Book 08'}) 
    CREATE (b09:Book {title:'Book 09'}) 
    CREATE (b10:Book {title:'Book 10'}) 

    CREATE (alice)-[:LOVES {how_much:0.1}]->(b01) 
    CREATE (alice)-[:LOVES {how_much:0.2}]->(b02) 
    CREATE (alice)-[:LOVES {how_much:0.3}]->(b03) 

    CREATE (bob)-[:LOVES {how_much:0.2}]->(b02) 
    CREATE (bob)-[:LOVES {how_much:0.4}]->(b04) 
    CREATE (bob)-[:LOVES {how_much:0.5}]->(b05) 
    CREATE (bob)-[:LOVES {how_much:0.6}]->(b06) 
    CREATE (bob)-[:LOVES {how_much:0.7}]->(b07) 

    CREATE (charlie)-[:LOVES {how_much:0.3}]->(b03) 
    CREATE (charlie)-[:LOVES {how_much:0.8}]->(b08) 
    CREATE (charlie)-[:LOVES {how_much:0.9}]->(b09) 
    CREATE (charlie)-[:LOVES {how_much:1.0}]->(b10) 

    CREATE (dan)-[:LOVES {how_much:0.1}]->(b01) 
    CREATE (dan)-[:LOVES {how_much:0.8}]->(b08) 

graph drawing

I хотел бы предложить книги Алисе таким образом, чтобы я рассматривал только верхние 2 LOVES отношения на каждого человека. Итак, для Алисы я бы посмотрел только на «Книгу 02» и «Книгу 03» (топ-2 книги). Эти книги свяжут меня с Бобем и Чарли (а не с Дэном, который связан с Алисой через ее наименее любимую книгу). В свою очередь, Боб свяжет Алису с «Книгой 06» и «Книга 07»; Чарли свяжет Алису с «Книга 09» и «Книга 10». В конце я хотел бы увидеть четыре рекомендации: «Книга 06» и «Книга 07» через Боба; и «Книга 09» и «Книга 10» через Чарли. Каков наиболее эффективный и эффективный запрос Neo4j для этой задачи?

Вот что я пытался сделать:

MATCH (alice:Person {name:'Alice'})-[la:LOVES]->(ba:Book)<-[lf:LOVES]-(friend:Person) 
    WITH alice, la 
    ORDER BY la.how_much DESC 
    WITH alice, COLLECT(la)[0..2] as alice_likes 
    UNWIND alice_likes as la 
    return * 

В этом, как я ограничить запрос к верхней 2 любит Элис. Однако я не знаю, как продолжить выполнение задачи. Я пытаюсь сделать следующее, но он не работает, как я ожидал:

MATCH (alice:Person {name:'Alice'})-[la:LOVES]->(ba:Book)<-[lf:LOVES]-(friend:Person) 
    WITH alice, la 
    ORDER BY la.how_much DESC 
    WITH alice, COLLECT(la)[0..2] as alice_likes 
    UNWIND alice_likes as la 


    MATCH (alice)-[la]->(ba:Book)<-[lf:LOVES]-(friend:Person) 
    WITH alice, la, lf, friend 
    ORDER by friend.name, lf.how_much DESC 
    WITH friend, collect(lf)[0..2] as friend_likes, collect(la)[0..2] as alice_likes 
    RETURN friend.name, friend_likes, alice_likes 
+1

Просьба предоставить положения 'CREATE' для отношений с Чарли и Дэном. – cybersam

+0

вы правы, @cybersam, обновленный –

ответ

1

Это должно работать:

MATCH (alice:Person { name:'Alice' })-[la:LOVES]->(:Book)<-[:LOVES]-(friend:Person) 
WITH alice, la, friend 
ORDER BY la.how_much DESC 
LIMIT 2 
MATCH (bf:Book)<-[lf:LOVES]-(friend:Person) 
WITH alice, lf, bf, friend 
ORDER BY lf.how_much DESC 
RETURN alice, friend, COLLECT(bf)[..2] AS books; 

Существует предположительно только один узел для ALice, поэтому мы можем использовать использовать LIMIT 2 чтобы получить две лучшие книги для нее.

Однако может быть несколько «друзей», которые также любят эти 2 книги, поэтому вы не можете использовать LIMIT 2, чтобы получить 2 книги для каждого из них (вместо этого вы получите только две лучшие книги для них как группа). Чтобы получить нужные результаты, этот запрос объединяет верхние книги для каждого друга, а затем выбирает верхнюю 2 (опять же для каждого друга).

+0

Это не будет работать, если Чарли любит книги 1, 2 и 3 тоже CREATE (чарли) - [: ЛЮБИТ {how_much: 0,2}] -> (b02) CREATE (чарли) - [: LOVES {how_much: 0.2}] -> (b01) –

+0

Пожалуйста, объясните, что не работает. Эти 2 предложения будут вводить самые низкие значения 'how_much' для Charlie, поэтому они не должны влиять на результаты. И, по моему тестированию, результаты не меняются, как и ожидалось. – cybersam

+0

Вы правы, моя ошибка –

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