2014-01-30 2 views
0

я получил Cypher-запрос, как это:Neo4j Cypher: вернуть некоторые атрибуты только если ROWCOUNT меньше порога

match (s)-[r]-(m) 
    where s.id='...' and r.id='...' 
    return s.id as id, s.title as title, s.content as content 

То, что я хотел бы добиться того, чтобы вернуться (потенциально очень большой) значение s.content, только если суммарный ряд строк меньше заданного порога (например, 5).

Я попытался

match (s:mytype)-[r:myothertype]-(m:mytype) 
    where s.id='...' and r.id='...' 
    return s.id as id, s.title as title, 
    case 
    when count(*) < 5 s.content 
    else null 
    end as content 

Этот запрос кажется синтаксически правильным, но он принимает навсегда, чтобы вернуться и в конечном итоге срывает мой сервер, даже с помощью всего 10 узлов и 4 отношений в базе данных.

Что я делаю неправильно?

Thanx заранее,

Jens

P.S. Просто, чтобы дать понять: я не хочу ограничивать результаты. Мне нужен идентификатор и заголовок для всех узлов во всех случаях.

ответ

2

Есть несколько вещей, которые могут вызывать проблемы с производительностью, но это зависит от ваших данных. Вы обобщили в своем примере, но предположим, что вы не указали индекс своих свойств для x.id.

Выполните следующий запрос, чтобы установить индекс на этикетке mytype для недвижимости id:

CREATE INDEX ON :mytype(id) 

Тогда, пожалуйста, попробуйте этот оптимизированный запрос. Вероятно, проблема заключается в том, что для каждого узла s вы выполняете агрегацию по счету для всей коллекции. Это кажется дорогостоящим.

MATCH (s:mytype { id: '...' }) 
MATCH (s)-[r:myothertype { id: '...'}]-(:mytype) 
WITH count(*) as content_weight 
MATCH (s:mytype { id: '...' }) 
MATCH (s)-[r:myothertype { id: '...'}]-(:mytype) 
WITH s, content_weight, 
    (CASE 
     WHEN content_weight < 5 THEN s.content 
     ELSE null 
     END) as content 
RETURN s.id, s.title, content 

Обновление: вы увидите здесь два матча. Есть еще один способ сделать этот запрос, используя предстоящую функцию в Cypher. На данный момент этот запрос должен выполняться нормально. Правильный способ сделать это - собрать на s, чтобы получить длину коллекции, а затем раскрутить коллекцию обратно в строки с весом содержимого. Извините за неудобства.

+0

У меня есть 100M записей в моем экземпляре neoj4, и он терпит неудачу, когда я пытаюсь co 'count()' на довольно большом наборе данных. Я бы не рекомендовал придерживаться этой идиомы, если вы не полностью уверены, что ваша система может справиться с этим. – tkroman

+0

Нет проблем с запуском 'count()' на большом наборе данных с использованием Cypher в Neo4j 2.0 GA. Если у вас возникли проблемы, пожалуйста, задайте вопрос здесь, на Stackoverflow или билет поддержки, если вы являетесь клиентом Neo4j. –

+0

Говорю вам, есть * проблема. Когда я запускаю 'start n = node (*) return count (*)' через веб-интерфейс, сервер зависает * полностью *. И я не единственный, кто переживает это. – tkroman

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