首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Neo4j密码中跨所有集合聚合相关节点

在Neo4j密码中跨所有集合聚合相关节点
EN

Stack Overflow用户
提问于 2018-11-14 14:07:06
回答 1查看 101关注 0票数 1

我最近开始使用Neo4j/cypher,并成功地构建了脑海中出现的大多数基本查询,但我想不到这个问题的解决方案。

节点有一个非常简单的关系模型:图书被分成不同的类别

这些书将是唯一的,并且可以与多个类别相关。

我的基本查询收集类别,生成一组图书及其关联的类别:

代码语言:javascript
复制
match (c:Category)-[:contains]-(b:Book)
return b as book, collect(distinct c) as categories

然后,我可以收集这些书籍,从而得到一组相关的书籍和类别:

代码语言:javascript
复制
match (c:Category)-[:contains]-(b:Book)
with b, collect(distinct c) as categories
return collect(distinct b) as books, categories

这似乎是在朝着正确的方向发展,但在整个过程中有许多重复的书籍和类别。下面是一个伪示例:

代码语言:javascript
复制
Books                         Categories
-----------------------------------------------
[Easy Home Updates]           [Home and Garden]
-----------------------------------------------
[Gardening Today,             [Outdoors,
 Gardening for Kids,           Hobbies,
 Green Thumb Made Easy]        Gardening]
-----------------------------------------------
[Conversational Spanish,      [Spanish,
 Spanish for Travelers,        Travel,
 Advanced Spanish]             Language]
-----------------------------------------------
[Gardening Today,             [Gardening,
 Gardening for Kids]           Kids]
-----------------------------------------------
[Home Improvement,            [Home Improvement,
 Easy Home Updates,            Home and Garden,
 Family Home Projects]         Family]
-----------------------------------------------
[Gardening Today]             [Gardening]
-----------------------------------------------
[Conversational Spanish,      [Language,
 Advanced Spanish]             Spanish]

我似乎找不到一种方法来聚合重复项,无论是在使用筛选的初始匹配中,还是在reduce和apoc函数中。

期望的结果将是同时减少图书和类别集合。如下所示:

代码语言:javascript
复制
Books                         Categories
----------------------------------------------
[Gardening Today,             [Gardening,
 Gardening for Kids,           Outdoors,
 Green Thumb Made Easy]        Hobbies,
                               Kids,
                               Family]
----------------------------------------------
[Conversational Spanish,      [Spanish,
 Spanish for Travelers,        Language,
 Advanced Spanish]             Travel,
                               Education]
----------------------------------------------
[Home Improvement,            [Home and Garden,
 Easy Home Updates,            Home Improvement,
 Family Home Projects]         Construction]

或者,也许我的方法完全错误,有一种更好、更有效的方法来对相关节点进行分组。

如果您能提供任何帮助来指引我正确的方向,我们将不胜感激。如果您需要进一步的澄清,请告诉我。

EN

回答 1

Stack Overflow用户

发布于 2018-11-14 19:10:18

创建你的模型

为了方便可能的进一步答案和解决方案,我注意到了我的图形创建语句:

代码语言:javascript
复制
CREATE
  (categoryHome:Category {name: 'Home and Garden'}),
  (categoryOutdoor:Category {name: 'Outdoors'}),
  (categoryHobby:Category {name: 'Hobbies'}),
  (categoryGarden:Category {name: 'Gardening'}),
  (categorySpanish:Category {name: 'Spanish'}),
  (categoryTravel:Category {name: 'Travel'}),
  (categoryLanguage:Category {name: 'Language'}),
  (categoryKids:Category {name: 'Kids'}),
  (categoryImprovement:Category {name: 'Home Improvement'}),
  (categoryFamily:Category {name: 'Family'}),
  (book1:Book {name: 'Easy Home Updates'}),
  (book2:Book {name: 'Gardening Today'}),
  (book3:Book {name: 'Gardening for Kids'}),
  (book4:Book {name: 'Green Thumb Made Easy'}),
  (book5:Book {name: 'Conversational Spanish'}),
  (book6:Book {name: 'Spanish for Travelers'}),
  (book7:Book {name: 'Advanced Spanish'}),
  (book8:Book {name: 'Home Improvement'}),
  (book9:Book {name: 'Easy Home Updates'}),
  (book10:Book {name: 'Family Home Projects'}),
  (categoryHome)-[:CONTAINS]->(book1),
  (categoryHome)-[:CONTAINS]->(book8),
  (categoryHome)-[:CONTAINS]->(book9),
  (categoryHome)-[:CONTAINS]->(book10),
  (categoryOutdoor)-[:CONTAINS]->(book2),
  (categoryOutdoor)-[:CONTAINS]->(book3),
  (categoryOutdoor)-[:CONTAINS]->(book4),
  (categoryHobby)-[:CONTAINS]->(book2),
  (categoryHobby)-[:CONTAINS]->(book3),
  (categoryHobby)-[:CONTAINS]->(book4),
  (categoryGarden)-[:CONTAINS]->(book2),
  (categoryGarden)-[:CONTAINS]->(book3),
  (categoryGarden)-[:CONTAINS]->(book4),
  (categorySpanish)-[:CONTAINS]->(book5),
  (categorySpanish)-[:CONTAINS]->(book6),
  (categorySpanish)-[:CONTAINS]->(book7),
  (categoryTravel)-[:CONTAINS]->(book5),
  (categoryTravel)-[:CONTAINS]->(book6),
  (categoryTravel)-[:CONTAINS]->(book7),
  (categoryLanguage)-[:CONTAINS]->(book5),
  (categoryLanguage)-[:CONTAINS]->(book6),
  (categoryLanguage)-[:CONTAINS]->(book7),
  (categoryKids)-[:CONTAINS]->(book2),
  (categoryKids)-[:CONTAINS]->(book3),
  (categoryImprovement)-[:CONTAINS]->(book8),
  (categoryImprovement)-[:CONTAINS]->(book9),
  (categoryImprovement)-[:CONTAINS]->(book10),
  (categoryFamily)-[:CONTAINS]->(book8),
  (categoryFamily)-[:CONTAINS]->(book9),
  (categoryFamily)-[:CONTAINS]->(book10);

解释

在我看来,您的技术实现是正确的,但从专业角度来看,您的需求并不一致。让我们选择一个例子。您预计会出现以下记录:

代码语言:javascript
复制
BOOKS:                        CATEGORIES:
Gardening Today,              Gardening,
Gardening for Kids,           Outdoors,
Green Thumb Made Easy         Hobbies,
                              Kids,
                              Family

通过执行以下Cypher查询,Family条目不是图书Gardening Today的有效类别。

代码语言:javascript
复制
MATCH (book:Book {name: 'Gardening Today'})<-[:CONTAINS]-(category:Category)
RETURN DISTINCT book.name, collect(category.name);

╒═════════════════╤═════════════════════════════════════════╕
│"book.name"      │"collect(category.name)"                 │
╞═════════════════╪═════════════════════════════════════════╡
│"Gardening Today"│["Kids","Gardening","Hobbies","Outdoors"]│
└─────────────────┴─────────────────────────────────────────┘

进行交叉检查,确认类别Family包含完整的其他书籍。

代码语言:javascript
复制
MATCH (category:Category {name: 'Family'})-[:CONTAINS]->(book:Book)
RETURN DISTINCT category.name, collect(book.name);
╒═══════════════╤═══════════════════════════════════════════════════════════════╕
│"category.name"│"collect(book.name)"                                           │
╞═══════════════╪═══════════════════════════════════════════════════════════════╡
│"Family"       │["Family Home Projects","Easy Home Updates","Home Improvement"]│
└───────────────┴───────────────────────────────────────────────────────────────┘

此过程将继续传播。这就是为什么你会得到不同的切片结果集的原因。所以你已经实现的方法是正确的:

代码语言:javascript
复制
MATCH path = (category:Category)-[:CONTAINS]->(book:Book)
WITH collect(category.name) AS categoryGroup, book.name AS bookName
RETURN categoryGroup, collect(bookName);

╒═════════════════════════════════════════════════════════════════╤═════════════════════════════════════════════════════════════════════╕
│"categoryGroup"                                                  │"collect(bookName)"                                                  │
╞═════════════════════════════════════════════════════════════════╪═════════════════════════════════════════════════════════════════════╡
│["Spanish","Travel","Language"]                                  │["Spanish for Travelers","Advanced Spanish","Conversational Spanish"]│
├─────────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────┤
│["Home Improvement","Family","Home and Garden","Home and Garden"]│["Easy Home Updates"]                                                │
├─────────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────┤
│["Hobbies","Gardening","Kids","Outdoors"]                        │["Gardening Today","Gardening for Kids"]                             │
├─────────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────┤
│["Hobbies","Gardening","Outdoors"]                               │["Green Thumb Made Easy"]                                            │
├─────────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────┤
│["Home Improvement","Family","Home and Garden"]                  │["Home Improvement","Family Home Projects"]                          │
└─────────────────────────────────────────────────────────────────┴─────────────────────────────────────────────────────────────────────┘

扩展

潜在的想法

因为请求的映射违反了赋值规则(集合论),所以我们不能使用通常的模式匹配。相反,我们可以通过一个技巧来实现我们的目标,即找到给定书籍的所有连接节点,并在之后为它们做好准备。

请确保已安装Neo4j APOC library

解决方案

代码语言:javascript
复制
MATCH (selectedBook:Book)
  WHERE selectedBook.name = 'Gardening for Kids'
CALL apoc.path.subgraphNodes(selectedBook, {uniqueness: 'NODE_GLOBAL'}) YIELD node
WITH collect(DISTINCT node) AS subgraphNodes
WITH
  filter (node IN subgraphNodes
    WHERE node:Category) AS categories,
  filter (node IN subgraphNodes
    WHERE node:Book) AS books
WITH categories, books
UNWIND categories AS category
UNWIND books AS book
RETURN collect(DISTINCT category.name) AS categoryNames, collect(DISTINCT book.name) AS bookNames;

解释

APOC第1-2行:在inspection

Book

  • 第10-13行对标识的节点进行排序:结果准备

结果

简易主页更新:

代码语言:javascript
复制
╒═══════════════════════════════════════════════╤═══════════════════════════════════════════════════════════════╕
│"categoryNames"                                │"bookNames"                                                    │
╞═══════════════════════════════════════════════╪═══════════════════════════════════════════════════════════════╡
│["Home and Garden","Family","Home Improvement"]│["Easy Home Updates","Family Home Projects","Home Improvement"]│
└───────────────────────────────────────────────┴───────────────────────────────────────────────────────────────┘

面向儿童的园艺:

代码语言:javascript
复制
╒════════════════════════════════════════╤════════════════════════════════════════╕
│"categoryNames"                         │"bookNames"                             │
╞════════════════════════════════════════╪════════════════════════════════════════╡
│["Kids","Gardening","Hobbies","Outdoors"│["Gardening for Kids","Gardening Today",│
│]                                       │"Green Thumb Made Easy"]                │
└────────────────────────────────────────┴────────────────────────────────────────┘
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53294084

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档