1

以下のように定義された User クラスがあります

class User
  include Neo4j::ActiveNode
  include Neo4j::Timestamps
  property :user_id, type: Integer, constraint: :unique
  property :max_friends_count, type: Integer, default: 5
  validates :user_id, :presence => true
  has_many :out, :followings, model_class: :GraphUser, rel_class: :GraphRel, unique: true
  has_many :in, :followers, model_class: :GraphUser, rel_class: :GraphRel, unique: true
end

それぞれ user_id 1 と 2 で とuser1を作成しました。user2

そして、 を使って次の次の次を検索します user1.followings(rel_length: 2)。しかし、との両方が互いにフォローし合っているuser1ため、結果はそれ自体として出てきます。user1user2

order(:breadth_first)すでにアクセスしたノードを除外するために、他の方法を試しました。私は十分な調査を行っていないかもしれませんが、これを行う方法を知っている人はいますか?

4

1 に答える 1

1

まず、 を使用することをお勧めしますid_propertypropertyforuser_idと setを使用するとconstraint: :unique、自動的に生成されたuuidプロパティが保持されます。それはあなたが望むものかもしれませんが、注意してください。のドキュメントは次のid_propertyとおりです。

https://github.com/neo4jrb/neo4j/wiki/Neo4j-v3-Unique-ID

あなたの質問に対して、あなたのコードはこれに似た Cypher を生成します (オプションmodel_classrel_classオプションを変更する必要がありました):

MATCH user15573
WHERE (ID(user15573) = {ID_user15573})
MATCH user15573-[rel1:`FOLLOWS`*2]->(result_followings:`User`)

Cypherの 1 つのMATCH句で、Neo4j は、1 つのパス トラバーサルで同じ関係が 2 回以上トラバースされないようにします。しかし、あなたが言ったように、それらが相互にフォローしている場合、それは他の関係をたどって元のユーザーに戻ることができることを意味します. その場合、潜在的な結果から元のユーザーを除外する必要があります。

MATCH user15573
WHERE (ID(user15573) = {ID_user15573})
MATCH user15573-[rel1:`FOLLOWS`*2]->(result_followings:`User`)
WHERE result_followings <> user15573

Ruby では次のようになります。

user1.as(:source).followings(:target, nil, rel_length: 2).where('source <> target')
于 2016-04-24T07:49:32.793 に答える