2015-11-24 4 views
1

Я хочу знать, как запрос пути был выполнен в neo4j. Например, у меня есть запрос путь, показанный ниже:Профилирование запроса пути Neo4j

match p=(n)-[r*1..10]->(m) 
where 
    (
    n.URI='http://yago-knowledge.org/resource/Jacob_T._Schwartz' OR 
    n.URI='http://yago-knowledge.org/resource/Anna_Karina' 
) AND 
    filter(x IN r where type(x)=~'.*hasAcademicAdvisor.*') AND 
    filter(y IN r where type(y)=~'.*isCitizenOf.*') AND 
    filter(z IN r where type(z)=~'.*participatedIn.*') AND 
    filter(u IN r where type(u)=~'.*happendedIn.*') AND 
    filter(v IN r where type(v)=~'.*dealsWith.*') 
return p, length(p) order by length(p) desc; 

Этот запрос, чтобы найти пути в базе данных графа с исходным узлом «http://yago-knowledge.org/resource/Jacob_T._Schwartz» или «http://yago-knowledge.org/resource/Anna_Karina», которые имеют определенные отношения.

Я использовал команду PROFILE с этим запросом, а ниже - план выполнения, который я получил.

enter image description here

Обратите внимание, что содержание в строке 5 цв 5 слишком долго, поэтому я ставлю *** вместо того, чтобы фактическое содержание.

На самом деле, *** обозначает ((((((Property(n,URI(0)) == { AUTOSTRING0} OR Property(n,URI(0)) == { AUTOSTRING1}) AND nonEmpty(FilterFunction(r,x,RelationshipTypeFunction(x) ~= /{ AUTOSTRING2}/))) AND nonEmpty(FilterFunction(r,y,RelationshipTypeFunction(y) ~= /{ AUTOSTRING3}/))) AND nonEmpty(FilterFunction(r,z,RelationshipTypeFunction(z) ~= /{ AUTOSTRING4}/))) AND nonEmpty(FilterFunction(r,u,RelationshipTypeFunction(u) ~= /{ AUTOSTRING5}/))) AND nonEmpty(FilterFunction(r,v,RelationshipTypeFunction(v) ~= /{ AUTOSTRING6}/)))

Извините за плохой формат.

Может кто-нибудь помочь мне объяснить план? Заранее спасибо!!!

ответ

1

Я верю, когда вы смотрите на план с текстовой консоли, которую вы читаете снизу вверх. Вы можете увидеть, что он сначала находит каждый единственный путь между n каждым другим узлом m, который имеет длину 1-10 (что, очевидно, много). После того, как он найдет все эти пути, он берет их и выбирает, какие из них следует хранить с фильтром.

Если вы можете, вы должны попробовать установить условия отношений на пути, а не в фильтр, чтобы Neo4j мог фильтровать по мере прохождения и останавливать перемещение, если он не соответствует, что может сэкономить вам много доступа к базе данных , Я заметил, что ваше соответствие типа отношений довольно свободно, так что я не знаю, как это трудно было бы, но если вы знаете все возможные типов отношений, то вы должны указать их следующим образом:

match p=(n)-[r:hasAcademicAdvisor|isCitizenOf|participatedIn|happendedIn|*1..10]->(m) 

Я d любопытны для получения дополнительной информации о том, почему вы используете регулярное выражение для соответствия типам отношений. Я знаю, что иногда люди вкладывают динамические значения в свои типы отношений (например, ID), и это, как правило, запах кода, по моему опыту. Часто вы можете использовать свойство отношений.

Несколько других заметок: вы не используете метки, поэтому, чтобы найти узлы с указанным вами свойством URI, сначала необходимо выполнить поиск по всей базе данных. Если вы используете метку и создаете индекс или ограничение на :Label(URI), тогда эта часть будет намного быстрее.

Я хотел бы также использовать IN, чтобы соответствовать URI в этом случае:

WHERE n.URI IN ('http://yago-knowledge.org/resource/Jacob_T._Schwartz', 'http://yago-knowledge.org/resource/Anna_Karina') 

Наконец, вы также должны иметь возможность воспользоваться регулярными выражениями, чтобы сделать это проще (и, возможно, более эффективно):

filter(x IN r where type(x)=~'.*(hasAcademicAdvisor|isCitizenOf|participatedIn|happendedIn|dealsWith).*') AND 

Но опять же, это не так эффективно, как положить его в ваш MATCH, если это возможно.

+0

Спасибо так много, Брайан. Да, у меня есть свои причины, использующие регулярное выражение для соответствия типам отношений. Фактически, в моем сценарии приложения я хочу найти пути между набором узлов, чтобы эти пути содержали все указанные отношения. Однако меня не волнует порядок отношений. Это единственный способ, которым я решил достичь своей цели. Кроме того, я согласился с вами о добавлении метки и использовании индекса для производительности. Я попробую! – sgao

+0

FWIW, синтаксис, который я дал, не указывает конкретный порядок, только то, что все отношения по пути должны быть одним из указанных типов. –

+0

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

0
  • Используйте этикетки,
  • Использование Neo4j 2,3.х,
  • Используйте ограничение на: ресурса (URI)
  • Учитывая, удаляя префикс URI из ваших значений URI, это просто отходы в БД, или заменить имен на импорт
  • не используют регэкспы для согласования отн типа, вы можете использовать осмысленные REL-тип, чтобы начать с
  • удалить двусмысленности из ваших отношений-типов

Попробуйте для запроса (после фиксации URIs и REL-типов)

match p=(n:Resource)-[:hasAcademicAdvisor|:isCitizenOf|:participatedIn|:happendedIn|:dealsWith*1..10]->(m:Resource) 
where n.URI IN ['Jacob_T._Schwartz', 'Anna_Karina'] 
return p, length(p) 
order by length(p) desc; 

Для запроса данных плана см обширных документов в Neo4j ручного

Также рассмотреть Neo4j браузер для более наглядного плана запроса

+0

Спасибо большое, Майкл. Я попробую то, что вы предложили. – sgao

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