Neo4j gem - Удалить повторяющиеся отношения

Я случайно создал повторяющиеся отношения ... теперь мне нужно их удалить. У нас есть сумасшедшие вещи в зашифрованном ответе здесь как с помощью cypher удалить повторяющиеся отношения между двумя узлами?

Сначала я задумался о том, чтобы найти отношения, а затем проверить их счет. Но это только в том случае, если я уже знаю два узла.

Мысли?

Обновить

Возможно, мне что-то не хватает, но я не думаю, что это укажет мне на дублирование user.friends.count > 1, поскольку это будет подсчитывать узлы. Я бы не знал, какие узлы считаются дважды

Единственный способ, которым я могу привлечь другого пользователя, - это выполнить второй цикл. Я думаю, это могло бы сработать, если бы first_rel_to и match_to можно было бы использовать непосредственно для пользователя без прокси-сервера запроса.

User.all.each do |user|
  user.friends.each do |friend|
    user.first_rel_to(friend).destroy if (user.match_to(friend).count > 1)   
  end
end

Итак .. это должно быть сделано ...?

Ответ: Да, это необходимо сделать

    User.all.each do |user|
      user.friends.each do |friend|
        user.friends.first_rel_to(friend).destroy if (user.friends.match_to(friend).count > 1)   
      end
    end

person Clam    schedule 22.01.2015    source источник
comment
Вы хотите что-то сверхэффективное или хотите что-то ленивое и легкое для запуска однажды?   -  person subvertallchris    schedule 22.01.2015
comment
мой db довольно маленький, и я собирался просто запустить его в консоли один раз. однако было бы любопытно узнать о различиях в том, что вы предлагаете   -  person Clam    schedule 22.01.2015
comment
user.friends.count возвращает количество друзей, возвращенных этим запросом, а не отдельных друзей.   -  person subvertallchris    schedule 23.01.2015
comment
да, но нам нужно посчитать отношения между одним пользователем и другим, поэтому я думаю, что третий комментарий в вашем ответе был опечаткой. Я запустил это в своей базе данных разработчиков, и я думаю, что это работает. если вы заметите что-то, чего мне не хватает, вы можете ответить, в противном случае я отредактирую ваш ответ позже и приму   -  person Clam    schedule 23.01.2015


Ответы (1)


Предполагая, что это одноразовая вещь, вы используете Neo4j.rb 4.1 и у вас нет возмутительного количества узлов для проверки, вот самый простой способ сделать это:

User.all.each do |user|
  user.friends.first_rel_to(other_user).destroy if user.friends.match_to(other_user).count > 1
end

Два запроса для каждого пользователя. Вам нужно будет заменить мой пример на тот, который возвращает счетчик и первое rel для ваших данных, но идея остается той же: используйте first_rel_to для удаления первой связи между узлами, если match_to этот другой узел сообщает вам, что существует более чем один отн.

Это также лучшее использование двух моих любимых методов в геме, first_rel_to и match_to, которое я когда-либо мог написать. Это правила. Я чувствую себя гордым родителем, который не перестанет хвастаться своим глупым чрезмерно успешным ребенком.

Обратной стороной здесь является то, что если у вас есть данные, хранящиеся в этом одном узле, вы их потеряете. Если вы хотите быть уверены, что удаляете нужный ...

User.all.each do |user|
  if user.friends.match_to(other_user).count > 1
    user.friends.match_to(other_user).each_rel do |rel|
      rel.destroy if rel.this_property.nil?
    end
  end
end

Прокрутите, если есть более одного rel, прокрутите rels, удалите тот, который вы определили как постороннее отношение.

Чтобы избежать этого в будущем, используйте параметр unique: true для ассоциаций или creates_unique_rel в ActiveRel.

Ответ Стефана хорош, если вам нужно что-то эффективное. Вам нужно будет изменить синтаксис START на MATCH.

person subvertallchris    schedule 22.01.2015
comment
Приятно знать, что мой вздор позволил вам продемонстрировать этот пример, лол. Вы сказали, что я потеряю данные узла? Вы имеете в виду данные об отношениях? возможный глупый вопрос: что входит other_user, это автоматически известно, когда вы делаете first_rel_to на friends - person Clam; 22.01.2015
comment
Могу ли я просто поместить его на это has_many :both, :friends, model_class: 'User', rel_class: 'FriendsWith, unique: true', у меня есть друзья_with, объявленные с помощью activerel, нужно ли что-нибудь с этим делать? - person Clam; 22.01.2015
comment
Нет, вы потеряете данные rel. other_node - это другой узел, к которому вы имеете отношение. Вам нужно найти способ понять это; в противном случае просто сделайте что-нибудь вроде if user.events.count > 1 then user.friends.each_rel.first.destroy. - person subvertallchris; 22.01.2015
comment
Я не думаю, что это правильно, посмотрите мои обновления в моем вопросе и дайте мне знать, если я сошел с ума. - person Clam; 22.01.2015
comment
Я смог найти только этот github.com / neo4jrb / neo4j / wiki / об уникальности, поэтому не был на 100% уверен, как правильно реализовать это с моей настройкой - person Clam; 23.01.2015