Простой запрос, объединяющий операторы подсчета в Cypher

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

CREATE (em0002: event: marriage { day: 16, month: 6, year: 1650, LOCAL_ID: 'em0002'})
CREATE (em0003: event: marriage { day: 16, month: 6, year: 1670, LOCAL_ID: 'em0003'})
CREATE (eb0001: event: baptism { day: 16, month: 6, year: 1665, LOCAL_ID: 'eb0001'})
CREATE (c0001: church: RCC { name: 'Kerk aan de Appelmarkt', location: 'Leiden', LOCAL_ID: 'c0001'})
CREATE (c0003: church: DRC { name: 'Gereformeerde Kerk', location: 'Leiden', LOCAL_ID: 'c0003'})
CREATE (em0001)-[:TOOK_PLACE_IN]->(c0001)
CREATE (em0003)-[:TOOK_PLACE_IN]->(c0001)
CREATE (eb0001)-[:TOOK_PLACE_IN]->(c0001)
CREATE (em0002)-[:TOOK_PLACE_IN]->(c0003)

Довольно легко получить количество крещений в определенный период, что можно сделать с помощью этого запроса:

WHERE e.year > 1650 AND e.year < 1680
RETURN count (e:baptism) AS Number_of_baptisms

Проблема в том, что я хочу создать обзор с количеством крещений в одном столбце и количеством браков в другом.

Я просто не знаю, как связать два запроса (один подсчитывает браки, а другой - крещения. Этот не дает правильного результата:

WHERE e.year_trouw > 1650 AND e.year_trouw < 1680 
MATCH (ee:baptism)-[:TOOK_PLACE_IN]->(ch:church:RCC {name: 'Kerk aan de Appelmarkt'})
WHERE ee.year > 1650 AND ee.year < 1680
RETURN count (e:marriage) AS Number_of_marriages, count (ee:baptism) AS Number_of_baptisms

person Jaap    schedule 24.10.2019    source источник


Ответы (2)


Возможно, что-то вроде этого? Подгоняй по своей логике

MATCH (e1:baptism), (e2:marriage)
WITH {baptism:COUNT(DISTINCT e1), marriage:COUNT(DISTINCT e2)} AS col
RETURN col.baptism AS Baptism, col.marriage AS Marriage
person Lju    schedule 24.10.2019
comment
Спасибо! Он работает, поскольку подсчитывает все события и делает различие между крещениями и браками, но не принимает во внимание параметр года (то есть период, в котором произошли эти события). - person Jaap; 28.10.2019
comment
Привет, просто добавьте параметры фильтра после строки ПОИСКПОЗ - я оставил это на ваше усмотрение :) - person Lju; 28.10.2019

В этом запросе используется функция REDUCE:

MATCH (event:event)
WHERE 1650 < event.year < 1680
RETURN REDUCE(s={b:0, m:0}, e IN COLLECT(event) |
  CASE WHEN e:baptism THEN {b:s.b+1, m:s.m} ELSE {b:s.b, m:s.m+1} END
) AS counts

для подсчета крещения/брака:

╒═════════════╕
│"counts"     │
╞═════════════╡
│{"b":1,"m":1}│
└─────────────┘

Запрос, как написано, предполагает, что любой event, который не является baptism, является marriage.

Кстати, такое выражение, как count(e:baptism), работает лучше, чем вы предполагали. e:baptism оценивает узел e, чтобы увидеть, имеет ли он метку baptism, и возвращает логическое значение. Итак, вы фактически подсчитываете общее количество истинных и ложных значений (т. е. общее количество узлов e). Вместо этого count(e) даст вам то же количество и будет более эффективным.

person cybersam    schedule 24.10.2019
comment
Большое спасибо, это работает как шарм. Мне придется внимательно изучить запрос, это выше моего мастерства! Спасибо также за объяснение функции подсчета. - person Jaap; 28.10.2019