简体   繁体   English

Neo4j Cypher:如何通过条件查询获取节点

[英]Neo4j Cypher: How to fetch nodes with conditional query on reation

I have two Neo4j Nodes and one relation: 我有两个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

Objective: My objective is get places & shared_places of staypal together but the shared places included if they are status == approved 目标:我的目标是一起获取Staypal的地点和shared_places,但如果状态==批准,则包括共享地点

Query: 查询:

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)

With this I am getting the places and shared places of staypal 有了这个,我得到了taypal的地方和共享的地方

But I want shared places where status = 1 但是我想要状态= 1的共享地点

Modified Query 修改后的查询

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)

But with this I am getting no records 但是与此相关的我没有任何记录

Some other helping queries 其他一些帮助查询

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)

Output: 输出:

[CypherRelationship 1239]

You are using the neo4j-core Query API, which you can do and which should allow you to get ActiveNode and ActiveRel objects, but there is a higher level API which is easier: 您正在使用neo4j-core查询API,您可以执行此操作,并且应该允许您获取ActiveNodeActiveRel对象,但是有一个更简单的高级API:

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

To do this I assumed that you add this association to Place : 为此,我假设您将此关联添加到Place

has_many :both, :shared_places, type: :shared_with

Note that I used the singular form for variables. 请注意,变量使用单数形式。 It's important to remember that when you are matching that it does one match at a time. 重要的是要记住,当您进行匹配时,它一次匹配一次。 Singular variables help us to keep that in context. 奇异变量有助于我们将其保持在上下文中。

Aside from that, though, I think you have a deeper issue that your HouseMate relationship is going from a Place to a StayPal . 但是除此之外,我认为您还有一个更深层次的问题,那就是,您的HouseMate关系正在从Place变为StayPal What is your model? 你的模特是什么? If you want to record two people staying in the same house, you might want to have a new node with a label like HouseMateGroup and that node could point to the Place as well as two (or more) StayPals. 如果要记录两个人住在同一所房子里,则可能要有一个带有HouseMateGroup类的标签的新节点,并且该节点可以指向Place以及两个(或多个)StayPal。

EDIT: 编辑:

I think I'm understanding your use case more. 我想我更了解您的用例。 I would probably make the model (:StayPal)-[:LIVES_IN]->(:Place)<-[:LIVES_IN]-(:StayPal) 我可能会制作模型(:StayPal)-[:LIVES_IN]->(:Place)<-[:LIVES_IN]-(:StayPal)

Any given step in that doesn't map to the idea of a "house mate", but you can easily get the housemates by following relationships/associations. 任何给定的步骤都不会映射到“室友”的概念,但是您可以通过遵循关系/关联轻松地获得室友。 So if you wanted to get housemates you might do: 因此,如果您想找室友,可以这样做:

pal = StayPal.find_by(user_id: 1)

pal.places.people

That would get you all of the people that are in the places which user_id: 1 is in. 这样一来,您将可以找到位于user_id: 1所在位置的所有人员。

If you wanted to find all places which have associated people: 如果要查找所有有相关人员的地方:

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

You could even count the number of people that exist in that relationship between places: 您甚至可以算出地方之间这种关系中存在的人数:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM