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

Я пишу программу, которая анализирует сообщения на форуме.
После загрузки тем форума в базу данных neo4j
я пытаюсь "ранжировать" сообщения. по количеству ответов, которые они получили.

Ответы включают прямые ответы, а также все поддерево для каждого прямого ответа.
Идея состоит в том, чтобы подсчитать все дочерние элементы дерева (это простое дерево без циклов). )

Каждое сообщение является узлом neo4j

# Create MSG nodes:
statement = "CREATE (c:MSG {id:{N}, title:{T}}) RETURN c"
for msg in msgs:
    graph.cypher.execute(statement, {"N": msg[0], "T": msg[1]})

Узел, который представляет сообщение, являющееся ответом на другое сообщение, имеет отношение r:CHILD_OF к его родительскому узлу.
корневые узлы не будут иметь отношения r:CHILD_OF, но будут иметь "0" как их родительский идентификатор

|parent id | msg id | Rank | List of all responses
+----------+--------+------+----------------------
|0         | 1051   | 3    | (1054, 1056, 1060)
|1051      | 1054   | 0    |
|1051      | 1056   | 1    | (1060)
|1056      | 1060   | 0    |
|0         | 1052   | 0    |

в этой таблице,

  • msg 1051 — это первое сообщение в теме.
  • msg 1052 — это первое сообщение в другой теме
  • msg 1051 получил 2 прямых ответа (1054, 1056) и еще один косвенный ответ (1060)
  • msg 1056 получил 1 прямой ответ (1060)

Мне нужно получить шифр, который может создать этот рейтинг.
Но не знаю, как его написать.
Проект на python, и я использую python 2.7, py2neo 2.0.3 , нео4дж 2.1.6


person Izack    schedule 07.01.2015    source источник


Ответы (2)


Этот запрос должен вернуть набор результатов, аналогичный вашей таблице (но без первого столбца):

MATCH (m:MSG)
OPTIONAL MATCH (c:MSG)-[:CHILD_OF*1..]->(m)
WITH m, COLLECT(DISTINCT c.id) AS childMsgIds
RETURN m.id AS `msg id`, LENGTH(childMsgIds) AS Rank, childMsgIds AS `List of all responses`

Соответствует ли это вашим потребностям?

person cybersam    schedule 08.01.2015
comment
Спасибо! это идеальный ответ. - person Izack; 09.01.2015

Это должно вернуть все отдельные дочерние элементы в дереве:

MATCH (message:MSG {id: {message_id}})<-[:CHILD_OF*0..]-(child:MSG)
RETURN DISTINCT child

Если вы хотите посчитать, вы можете сделать RETURN COUNT(DISTINCT child)

person Brian Underwood    schedule 07.01.2015
comment
Спасибо, я проголосовал за этот ответ, потому что он в правильном направлении. Две незначительные проблемы: вам нужно считать с 1, а не с 0, и это вернет ответ только для определенного узла. - person Izack; 08.01.2015
comment
Ах, хорошее замечание по поводу 0/1. Я поставил id, потому что, кажется, это было то, что вы хотели от своего вопроса. - person Brian Underwood; 09.01.2015