【问题标题】:Neo4j Cypher: How to fetch nodes with conditional query on reationNeo4j Cypher:如何通过对关系的条件查询来获取节点
【发布时间】:2016-12-15 19:44:23
【问题描述】:

我有两个 Neo4j 节点和一个关系:

class StayPal
  include Neo4j::ActiveNode

  has_many :in, :places, origin: :owner
  has_many :in, :shared_places, rel_class: 'HouseMate'
end

class Place
  include Neo4j::ActiveNode

  has_one :out, :owner, type: :owner_of, model_class: 'StayPal'
  has_many :out, :house_mates, rel_class: 'HouseMate'
end

class HouseMate
  include Neo4j::ActiveRel
  include Enumable

  creates_unique

  from_class 'Place'
  to_class 'StayPal'
  type 'shared_with'

  property :status, default: 0

  enum_attr status: [:pending, :approved, :declined, :cancelled]
end

目标:我的目标是把地方和 shared_places 放在一起,但如果它们的状态 == 批准,则包括共享的地方

查询:

Neo4j::Session.current.query
  .match(n: { StayPal: { user_id: 1 } })
  .match('n<-[rel1:`owner_of`]-(result_places:`Place`)')
  .match('n<-[rel2:`shared_with`]-(result_places1:`Place`)')
  .pluck(:result_places1, :result_places)

有了这个,我得到了住宿的地方和共享的地方

但我想要共享位置,其中状态 = 1

修改后的查询

Neo4j::Session.current.query
  .match(n: { StayPal: { user_id: 1 } })
  .match('n<-[rel1:`owner_of`]-(result_places:`Place`)')
  .match('n<-[rel2:`shared_with`]-result_places1:`Place`)')
  .where('result_places1.status = 1')
  .pluck(:result_places1, :result_places)

但是我没有得到任何记录

其他一些帮助查询

Neo4j::Session.current.query
  .match(n: { StayPal: { user_id: 1 } })
  .match('n<-[rel1:`owner_of`]-(result_places:`Place`)')
  .match('n<-[rel2:`shared_with`]-result_places1:`Place`)')
  .where('result_places1.status = 1')
  .pluck(:result_places1)

输出:

[CypherRelationship 1239]

【问题讨论】:

    标签: ruby-on-rails neo4j cypher neo4j.rb


    【解决方案1】:

    您正在使用 neo4j-core 查询 API,您可以这样做并且应该允许您获取 ActiveNodeActiveRel 对象,但有一个更简单的更高级别的 API:

    StayPal.where(user_id: 1).places(:place1).shared_places(:places2).pluck(:place1, place2)
    

    为此,我假设您将此关联添加到Place

    has_many :both, :shared_places, type: :shared_with
    

    请注意,我对变量使用了单数形式。重要的是要记住,当您匹配时,它一次只匹配一个。奇异变量有助于我们将其保持在上下文中。

    不过,除此之外,我认为您还有一个更深层次的问题,即您的HouseMate 关系正在从一个地方变为StayPal。你的型号是什么?如果您想记录两个人住在同一所房子里,您可能需要一个带有HouseMateGroup 之类标签的新节点,并且该节点可以指向 Place 以及两个(或更多)StayPals。

    编辑:

    我想我更了解您的用例。我可能会制作模型(:StayPal)-[:LIVES_IN]-&gt;(:Place)&lt;-[:LIVES_IN]-(:StayPal)

    任何给定的步骤都不会映射到“室友”的想法,但您可以通过关注关系/关联轻松获得室友。所以如果你想找室友,你可以这样做:

    pal = StayPal.find_by(user_id: 1)
    
    pal.places.people
    

    这会让你找到user_id: 1所在位置的所有人。

    如果您想查找所有与人相关的地方:

    Place.as(:place1).people.places(:place2).pluck(:place1, :place2)
    

    您甚至可以计算出存在于该地区之间关系中的人数:

    Place.as(:place1).people(:person).places(:place2).pluck(:place1, :place2, 'count(person)')
    

    【讨论】:

    • (对不起,如果这个答案不是很准确,我必须很快回答。如果您有其他问题,也可以通过我们的 Gitter 频道gitter.im/neo4jrb/neo4j
    • 是的,我需要两个或两个以上的人住在同一所房子里,一个人是主人,其他人是通过邀请来的,我们有不同的身份(批准/拒绝)...... ..在一个房子里添加这个多个用户之前,我只有一个地方,一个所有者类型的功能,已经有数据库..任何帮助处理这个查询............我希望用户拥有自己的地点以及其他所有者与他分享的地方?
    • 我很困惑(:StayPal)-[:LIVES_IN]-&gt;(:Place)&lt;-[:LIVES_IN]-(:StayPal)这很好,但我必须维护邀请系统,要求人们共享房间..所以我需要家庭伴侣关系才能这样做......什么是您在查询中提到的人??....并且地方和所有者关系已经与生产中的数据存在所以只需要添加要求其他用户(staypals)共享房间的室友功能
    • 你可以有另一个关系,比如(:StayPal)-[:REQUESTED_STAY_IN]-&gt;(:Place) 或类似的东西,对吧?然后,如果请求获得批准,您可以将其替换为 LIVES_IN。但是如果它已经在生产中,那显然会更棘手,但是neo4j gem 的 8.0 确实提供了迁移功能。随意忽略我对标签/关系类型的建议,但是关联链接语法有意义吗?我建议看这个系列:youtube.com/playlist?list=PL5klM3mD6alLUhNTPTbj5a3GBjU7oZN0t
    猜你喜欢
    • 1970-01-01
    • 2020-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-29
    • 1970-01-01
    相关资源
    最近更新 更多