[ОБНОВЛЕНО]
Вот простой и эффективный запрос (для которого нужен только один MATCH
). Например, если список имен авторов передается в параметре authNames
, :
MATCH (b)<-[:WROTE]-(a:Author)
WHERE a.name IN $authNames
WITH {name: b.title, published: b.published, authors: COLLECT(a.name)} AS item
ORDER BY b.published
RETURN COLLECT(item) AS books
COLLECT(a.name)
используется для преобразования значения authors
в список, поскольку у книги, как правило, может быть несколько авторов.
Вы также можете создать индекс по Author(name)
для оптимизации запроса.
Дополнение
Если если вы хотите получить отсортированный по дате список данных книги (с возможно разными свойствами, из разных частей БД), вы можете использовать новую поддержку обработки после объединения . Например, если вы хотите получить отсортированный список книг, написанных автором в $authNames
или рецензированных рецензентом в $revNames
:
CALL {
MATCH (b)<-[:WROTE]-(a:Author)
WHERE a.name IN $authNames
RETURN {name: b.title, published: b.published, authors: COLLECT(a.name)} AS item
UNION ALL
MATCH (b)<-[:REVIEWED]-(r:Reviewer)
WHERE r.name IN $revNames
RETURN {name: b.title, published: b.published, reviewers: COLLECT(r.name)} AS item
}
WITH item.name AS name, apoc.map.mergeList(COLLECT(item)) AS merged
ORDER BY merged.published
RETURN COLLECT(merged) AS books
UNION ALL - это используется (вместо UNION
), чтобы избежать усилий по удалению дубликатов, потому что в этом примере два подзапроса не должны создавать повторяющиеся элементы. Для дополнительных подзапросов можно добавить еще UNION
s.
Используется функция apo c .map.mergeList (вместе с функцией агрегирования COLLECT
), чтобы объединить данные об авторе и рецензенте одной и той же книги в единую карту.