Neo4j найти все узлы с соответствующими свойствами

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

Любые идеи о том, как действовать? Не находить начальных точек в документах neo4j. Я участвую в выпуске сообщества 1.8.2.

ИЗМЕНИТЬ
Извините за то, что вы не поняли начальный вопрос, но я говорю об этом через Cypher.

Ответ 1

Cypher для подсчета значений свойства, возвращая также набор узлов:

start n=node(*)
where has(n.prop)
with n.prop as prop, collect(n) as nodelist, count(*) as count
where count > 1
return prop, nodelist, count;

Пример консоли: http://console.neo4j.org/r/k2s7aa

Вы также можете выполнить сканирование индекса с таким свойством (чтобы не смотреть на узлы, которые не имеют этого свойства):
start n=node:node_auto_index('prop:*') ...

2.0 Cypher с меткой Метка:

match (n:Label)
with n.prop as prop, collect(n) as nodelist, count(*) as count
where count > 1
return prop, nodelist, count;

Ответ 2

Как насчет следующего подхода:

  • используйте getAllNodes, чтобы получить итерацию по всем узлам.
  • используя getPropertyKeys и getProperty (ключ) создайте java.util.Map, содержащий все свойства для node. Вычислить карту hashCode()
  • создайте глобальный Map, используя ключ hashCode as и набор node.getId() как значения

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

Ответ 3

Вы можете попробовать этого, кто делает то, что я думаю, делает все, что вы хотите.

START n=node(*), m=node(*)
WHERE 
  HAS(n.name) AND HAS (m.name) AND 
  n.name=m.name AND 
  ID(n) <ID(m) 
RETURN n, m

http://console.neo4j.org/?id=xe6wmt

Оба узла должны иметь свойство name. name должен быть равен для обоих узлов, и нам нужна только одна пара двух возможных, которые мы получаем через сравнение id. Не уверен в производительности - пожалуйста, проверьте.

Ответ 4

Самый лучший/самый простой вариант - сделать что-то вроде локального Map. Если вы сделали что-то подобное, вы можете создать такой код:

GlobalGraphOperations ggo = GlobalGraphOperations.at(db);
Map<Object, Node> duplicateMap = new HashMap<Object, Node>();

for (Node node : ggo.getAllNodes()) {
    Object propertyValue = node.getProperty("property");
    Node existingNode = duplicateMap.get(propertyValue);
    if (existingNode == null) {
        duplicateMap.put(propertyValue, node);
    } else {
        System.out.println("Duplicate Node. First Node: " + existingNode + ", Second Node: " + node);
    }
}

Это приведет к распечатке списка. Если вам нужно сделать больше, например удалить эти узлы, вы можете сделать что-то в другом.

Знаете ли вы название свойства? Будет ли это несколько свойств или просто дубликатов одной пары имя/значение? Если вы выполняете несколько свойств, просто создайте карту для каждого свойства, которое у вас есть.

Ответ 5

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

Ответ 6

Neo4j 3.1.1

HAS больше не поддерживается в Cypher, вместо этого используйте EXISTS.

Если вы хотите найти узлы с определенным свойством, Cyper выглядит следующим образом:

MATCH (n:NodeLabel) where has(n.NodeProperty) return n