Neo4j Cypher:如何在reation上使用条件查询获取节点

时间:2016-12-15 19:44:23

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

我有两个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

目标:我的目标是获取地点& staypal的stay_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)

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

但我想要status = 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]

1 个答案:

答案 0 :(得分:0)

您正在使用neo4j-core查询API,您可以执行该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]->(:Place)<-[: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)')