У меня есть один узел и одно отношение

class User
  include Neo4j::ActiveNode

  property :first_name
end


class Connection
  include Neo4j::ActiveRel
  include Enumable

  creates_unique

  from_class 'User'
  to_class 'User'
  type 'connected_to'

  property :status, type: Integer, default: 0
end

Я хочу найти подключенного пользователя второй степени от пользователя User1, который еще не связан с пользователем1

User.find(1).query_as(:s)
  .match('(s) - [r1 :connected_to] - (mutual_friend) 
    - [r2 :connected_to] - (friends_of_friend: `User`)')
  .match('(s)-[r4:connected_to]-[friends_of_friend]')
  .where('r1.status = 1 AND r2.status = 1 AND r4 IS NULL')
  .pluck('DISTINCT friends_of_friend.uuid').count

Но это дает мне 0 результатов каждый раз, когда я также пробовал с необязательным совпадением, но это давало огромное количество. Любая помощь по этому вопросу?

0
Vishal G 24 Апр 2017 в 22:56

2 ответа

Лучший ответ

MATCH нельзя использовать, чтобы найти отсутствие шаблона, который никогда не вернет строки. Использование OPTIONAL MATCH вместо этого должно работать.

Или, если метод where_not() разрешает шаблоны, вы можете использовать:

 .where_not('(s)-[:connected_to]-(friends_of_friend)')

В качестве альтернативы означает исключить эти отношения.

1
Brian Underwood 25 Апр 2017 в 12:24

InverseFalcon прав, хотя есть несколько других вещей, которые вы можете сделать, чтобы сделать его намного проще:

class User
  include Neo4j::ActiveNode

  property :first_name

  has_many :both, :connected_users, type: :connected_to, model_class: :User
end


# ActiveRel isn't strictly needed for this,
# though to have the `default` or any other logic it's good to have it


user = User.find(1)

user.as(:user)
    .connected_users.rel_where(status: 1)
    .connected_users(:friend_of_friend).rel_where(status: 1)
    .where_not('(user)-[:connected_to]-(friend_of_friend)')
    .count(:distinct)

Я думаю, что это также будет работать:

user.as(:user)
    .connected_users(:friend_of_friend, nil, rel_length: 2).rel_where(status: 1)
    .where_not('(user)-[:connected_to]-(friend_of_friend)')
    .count(:distinct)
2
Brian Underwood 26 Апр 2017 в 00:43