首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >neo4j查询列表中至少有一项的数组字段

neo4j查询列表中至少有一项的数组字段
EN

Stack Overflow用户
提问于 2021-04-22 06:17:00
回答 2查看 91关注 0票数 0

我想用一个列表查询一个列表

代码语言:javascript
复制
 p = ['Author-1', Author-2, Author-2]
 a = ['Author-1', Author-2]
 b = ['Author-1', Author-2, Author-3, Author-4]
 c = ['Author-4', Author-5, Author-6, Author-7]
 d = ['Author-5', Author-6, Author-7, Author-8]

如果其中一个列表至少有author1或author2,则使用p返回它。

代码语言:javascript
复制
WITH p, a, b, c
UNWIND p
WITH DISTINCT p
MATCH (p)
with b as book, collect(g) as genre
WHERE genre in b.genre
return book.isbn, genre

我的实际示例没有返回任何内容,该类型类似于上面示例中的p,而b.genre类似于b、c、d、e,WHERE genre in b.genre没有正常工作。

代码语言:javascript
复制
MATCH (c:Customer { name : "Andrei Balanuta" })-[:CLIENT]-(o:Order)-[ol:ORDERLINE]-(b:Book)
UNWIND b.genre as  g
WITH DISTINCT g
MATCH (b:Book)
with b as book, collect(g) as genre
WHERE genre in b.genre
return book.isbn, genre
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-04-22 14:13:43

在您的实际示例中,如果您有关于:Book(流派)的索引,我们可以将其作为索引查找。

另外,我们不需要使用以后永远不会被重用的变量。

代码语言:javascript
复制
MATCH (:Customer { name : "Andrei Balanuta" })-[:CLIENT]-(:Order)-[:ORDERLINE]-(b:Book)
WITH collect(DISTINCT b.genre) as genres
MATCH (b:Book)
WHERE b.genre IN genres
WITH DISTINCT b as book
RETURN book.isbn, book.genre

也就是说,让所有类型的书都与以前订购的书相匹配似乎有点过火了,也许限制或额外的过滤可能是个好主意。

对于更一般的示例,可以使用any() list谓词

https://neo4j.com/docs/cypher-manual/current/functions/predicate/#functions-any

代码语言:javascript
复制
WITH ['Author-1', 'Author-2', 'Author-2'] as p,
 ['Author-1', 'Author-2'] as a,
 ['Author-1', 'Author-2', 'Author-3', 'Author-4'] as b,
 ['Author-4', 'Author-5', 'Author-6', 'Author-7'] as c,
 ['Author-5', 'Author-6', 'Author-7', 'Author-8'] as d,
 ['Author-1', 'Author-2'] as desired
UNWIND [p, a, b, c, d] as list
WITH desired, list
WHERE any(item IN desired WHERE item IN list)
RETURN list
票数 0
EN

Stack Overflow用户

发布于 2021-04-22 13:39:41

我看到了几种你能做到的方法。我认为最简单的方法是搜索列表中的每一种类型,然后汇总结果。

代码语言:javascript
复制
MATCH (c:Customer { name : "Andrei Balanuta" })-[:CLIENT]-(o:Order)-[ol:ORDERLINE]-(b:Book)
UNWIND b.genre as  g
WITH DISTINCT g
MATCH (b:Book)
WHERE g in b.genre
RETURN book.isbn, collect(g) AS genre

如果安装了APOC库,还可以使用apoc.coll.intersection函数。像这样的东西也许能满足你的需要。

代码语言:javascript
复制
MATCH (c:Customer { name : "Andrei Balanuta" })-[:CLIENT]-(o:Order)-[ol:ORDERLINE]-(b:Book)
UNWIND b.genre as  g
WITH collect(distinct g) as customerGenres
MATCH (b2:Book)
WHERE size(apoc.coll.intersection(customerGenres, b2.genre)) > 0
RETURN b2.isbn, b2.genre, customerGenres

以上两个查询都将包括客户已经购买的书籍。如果你想避免这种情况,你可以这样做。

代码语言:javascript
复制
MATCH (c:Customer { name : "Andrei Balanuta" })-[:CLIENT]-(o:Order)-[ol:ORDERLINE]-(b:Book)
WITH COLLECT (b) as customerBooks
WITH customerBooks, 
apoc.coll.toSet([book in customerBooks | book.genre]) as customerGenres
MATCH (b2:Book)
WHERE size(apoc.coll.intersection(customerGenres, b2.genre)) > 0
AND NOT b2 in customerBooks
RETURN b2.isbn, b2.genre, customerGenres

最后,所有这些查询都必须搜索数据库中的每一本书,以检查类型属性。如果查询性能开始陷入困境,您可能会考虑将类型设置为节点而不是属性。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67207739

复制
相关文章

相似问题

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