cypher多个可选匹配条件

时间:2017-05-13 19:26:21

标签: neo4j cypher

我在数据库中有三个对象:Person,Country和Car,可以使用

创建
create (:Car { name: 'car-987' })
create (:Car { name: 'car-876' })
create (:Country { name: 'country-123' })
create (:Country { name: 'country-234' })
create (:Country { name: 'country-345' })
match (cnt:Country { name: 'country-123' }), (cr:Car { name: 'car-987' }) create (cr)<-[:HAS_CAR]-(:Person { name: 'person-abc' })-[:LIVES_IN]->(cnt)
match (cnt:Country { name: 'country-234' }) create (:Person { name: 'person-bcd' })-[:LIVES_IN]->(cnt)
match (cr:Car { name: 'car-876' }) create (cr)<-[:HAS_CAR]-(:Person { name: 'person-cde' })

我正在选择具有可选国家/地区和汽车信息的人物对象

match (prs:Person)
optional match (prs)-[:LIVES_IN]->(cnt:Country)
optional match (prs)-[:HAS_CAR]->(cr:Car)
return id(prs) as id, prs.name as person, cnt.name as country, cr.name as car
order by person asc

结果是:

╒════╤════════════╤═════════════╤═════════╕
│"id"│"person"    │"country"    │"car"    │
╞════╪════════════╪═════════════╪═════════╡
│62  │"person-abc"│"country-123"│"car-987"│
├────┼────────────┼─────────────┼─────────┤
│63  │"person-bcd"│"country-234"│null     │
├────┼────────────┼─────────────┼─────────┤
│64  │"person-cde"│null         │"car-876"│
└────┴────────────┴─────────────┴─────────┘

如果我试图使用某些条件,问题就会出现。例如,我只需要获取country.name包含'4'或car.name包含'6'的记录。 有了这样的条件,我希望得到:

╒════╤════════════╤═════════════╤═════════╕
│"id"│"person"    │"country"    │"car"    │
╞════╪════════════╪═════════════╪═════════╡
│63  │"person-bcd"│"country-234"│null     │
├────┼────────────┼─────────────┼─────────┤
│64  │"person-cde"│null         │"car-876"│
└────┴────────────┴─────────────┴─────────┘

我怎样才能实现它? 如果我想在OPTIONAL MATCH中使用WHERE

match (prs:Person)
optional match (prs)-[:LIVES_IN]->(cnt:Country) where cnt.name contains '4'
optional match (prs)-[:HAS_CAR]->(cr:Car) where cr.name contains '6'
return id(prs) as id, prs.name as person, cnt.name as country, cr.name as car
order by person asc

获得不期望的结果:

╒════╤════════════╤═════════════╤═════════╕
│"id"│"person"    │"country"    │"car"    │
╞════╪════════════╪═════════════╪═════════╡
│62  │"person-abc"│null         │null     │
├────┼────────────┼─────────────┼─────────┤
│63  │"person-bcd"│"country-234"│null     │
├────┼────────────┼─────────────┼─────────┤
│64  │"person-cde"│null         │"car-876"│
└────┴────────────┴─────────────┴─────────┘

还在考虑使用像

这样的东西
match (prs:Person),
(prs)-[:LIVES_IN*0..1]->(cnt:Country),
(prs)-[:HAS_CAR*0..1]->(cr:Car)
where cnt.name contains '4' or cr.name contains '6'
return id(prs) as id, prs.name as person, cnt.name as country, cr.name as car
order by person asc

但是这个不会返回任何记录。

1 个答案:

答案 0 :(得分:2)

您已关闭,请尝试保留您的OPTIONAL MATCH,但使用WITH和WHERE子句强制执行剩余的过滤:

match (prs:Person)
optional match (prs)-[:LIVES_IN]->(cnt:Country)
optional match (prs)-[:HAS_CAR]->(cr:Car) 
with prs, cnt, cr
where cnt.name contains '4' or cr.name contains '6'
return id(prs) as id, prs.name as person, cnt.name as country, cr.name as car
order by person asc