2016-09-22 7 views
0

У меня есть база данных с сущностями человек (имя, возраст) и проект (имя). Можно ли запросить базу данных в cypher, которая указывает мне, что это человек или проект?Свойство узла запроса Neo4j.

для примера рассмотрим у меня есть эти два экземпляра для каждого:

Node (имя = Алиса, возраст = 20) Node (имя = Bob, возраст = 31)

Node (имя = project1) Узел (name = project2)

-I хочу знать, есть ли способ, который я только что сказал project1, и он говорит мне, что это проект.

-или я спрашиваю Алису, и это говорит мне, что это человек?

Благодаря

ответ

2

Вы должны использовать узел метку (как Person и Project) для представления узла "типов".

Например, чтобы создать человека и проект:

CREATE (:Person {name: 'Alice', age: 20}) 
CREATE (:Project {name: 'project1'}) 

Чтобы найти проект (ы) с именем 'Фред:

MATCH (p:Project {name: 'Fred'}) 
RETURN p; 

Чтобы получить коллекцию этикеток узла n, вы можете вызвать функцию LABELS(n). Затем вы можете посмотреть в этой коллекции, чтобы увидеть, есть ли там ярлык, который вы ищете. Например, если ваш запрос Cypher каким-то образом получает узел n, то этот фрагмент будет возвращать n тогда и только тогда, когда он имеет Person ярлык:

. 
. 
. 
WHERE 'Person' IN LABELS(n) 
RETURN n; 

[ОБНОВЛЕНО]

Если вы хотите, чтобы найти все узлы со значением name собственности «Фред»:

MATCH (n {name: 'Fred'}) 
... 

Если вы хотите, чтобы найти все отношения с именем значение свойства «Фред»:

MATCH()-[r {name: 'Fred'})-() 
... 

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

OPTIONAL MATCH (n {name: 'Fred'}) 
OPTIONAL MATCH()-[r {name: 'Fred'})-() 
... 
+0

@Eli Вы можете просмотреть [ссылочную карту] Cypher (https://neo4j.com/docs/cypher-refcard/current/) с акцентом на раздел «Этикетки». – InverseFalcon

+0

@InverseFalcon Спасибо за ответ. Мой вопрос на один уровень выше. Например, я запрашиваю термин «X», и я хочу знать, что это свойство узла или свойства отношения. Тогда я знаю, что термин «Х» - это человек или проект. У cypher есть эта способность? – Eli

+0

@Eli: Я (@cybersam) недавно обновил свой ответ, и он показывает, что вы можете использовать функцию 'LABELS', чтобы найти метки любого узла. – cybersam

2

Так что ваш случай использования искать вещи по имени, и эти вещи могут быть несколько типов вместо одного типа.

Просто отметить, в общем, это не то, для чего построен Neo4j. Обычно в запросах Neo4j вы знаете тип вещи, которую ищете, и исследуете отношения между этой вещью (или вещами), чтобы выяснить ассоциации или данные, полученные из этого.

Тем не менее, есть способы, чтобы сделать это, хотя это стоит идти через остальную часть случаев использования и увидеть, если Neo4j действительно лучший инструмент для того, что вы пытаетесь сделать

Всякий раз, когда вы находитесь запрашивая свойство, вы либо хотите получить уникальное ограничение на метку/свойство, либо индекс на ярлыке/свойстве. Обратите внимание, что для этого вам нужна комбинация ярлыка и свойства; вы не можете вслепую попросить узел с свойством без указания метки и получить хорошую производительность, так как придется выполнять сканирование всех узлов в вашей базе данных (в Neo4j есть некоторые старые ручные индексы, но я не уверен, что они будут по-прежнему поддерживаться, индексы схемы рекомендуются разработчиками).

Существует обходное решение, так как Neo4j позволяет использовать несколько меток на одном узле. Если вы хотите только запросить определенные типы по имени (например, только проекты и люди), вы можете создать: Именованный ярлык и установить этот ярлык для всех: Project и: Person (и любые другие метки, на которые он должен применяться) , Затем вы можете создать индекс на: Named.name. Таким образом, ваш запрос будет что-то вроде:

MATCH (n:Named) 
WHERE n.name = 'blah' 
WITH LABELS(n) as types 
WITH FILTER(type in types WHERE type <> 'Named') as labels 
RETURN labels 

Имейте в виду, что вы не указали, если имя должно быть уникальным среди типов узлов, так что это может быть возможно для: Человек или: Проект или множественным : Лица, имеющие одно и то же имя, не уверены, как это повлияет на то, что должно произойти с вашей стороны. Если каждая именованная вещь должна иметь уникальное имя, вы должны создать уникальное ограничение на: Named.name (хотя, опять же, вам нужно убедиться, что каждый созданный вами узел должен быть: Именованный имеет: Именованный ярлык, применяемый при создании).

+0

Спасибо, ваш ответ прав. Я думал, что база данных графа является вариантом для таких запросов. Я изучаю варианты ответа на поиск высокого уровня («X» - это человек, местоположение, проект и т. Д.). Что вы предлагаете мне найти для ответа на такие вопросы? – Eli

+0

Например, как Google знает, что Том Хэнкс является человеком и возвращает мне подробную информацию о человеке? – Eli

+0

Возможно, вы захотите посмотреть ElasticSearch, но в целом я думаю, что вы ищете решения db, которые используют инвертированные индексы. Что касается Google, Google не просто использует одно решение для баз данных, большая часть того, что они делают, является доморощенным (и представила или вдохновила несколько современных технологий). Когда дело доходит до текстового соответствия, не зная контекста, dbs с использованием инвертированных индексов, вероятно, являются лучшими местами для начала. Они также позволяют повысить результаты на основе различных критериев, которые звучат так же, как вы просите. – InverseFalcon

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