Helpers - компьютеры, интернет, программирование

Поиск всех пользователей с повторяющимися именами

У меня есть пользователи, у которых есть поля first_name и last_name, и мне нужно сделать ruby, чтобы найти всех пользователей, у которых есть дубликаты учетных записей на основе имени и фамилии. Например, я хочу иметь поиск, который будет искать среди всех других пользователей и находить, есть ли у кого-то такое же имя и адрес электронной почты. Я думал о вложенном цикле, подобном этому

User.all.each do |user|
 //maybe another loop to search through all the users and maybe if a match occurs put that user in an array
end

Есть ли способ лучше


  • Вы проверяете это перед сохранением нового пользователя или вам нужно найти дубликатов пользователей? 30.12.2010
  • Мне нужно найти повторяющихся пользователей 30.12.2010
  • Имена пользователей регулярно будут дублироваться. Если вы используете их имена для предоставления уникальных учетных записей, вы без необходимости ограничите свою пользовательскую базу. Вместо этого начните с их адреса электронной почты, который будет уникальным в Интернете. 31.12.2010

Ответы:


1

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

User.find(:all, :group => [:first, :email], :having => "count(*) > 1" )

Это вернет массив, содержащий одну из каждой из дублированных записей. Исходя из этого, скажем, у одного из возвращенных пользователей были «Fred» и «[email protected]», тогда вы можете искать только пользователей, имеющих эти значения, чтобы найти всех затронутых пользователей.

Возврат от этого find будет примерно следующим. Обратите внимание, что массив содержит только одну запись из каждого набора дублированных пользователей.

[#<User id: 3, first: "foo", last: "barney", email: "[email protected]", created_at: "2010-12-30 17:14:43", updated_at: "2010-12-30 17:14:43">, 
 #<User id: 5, first: "foo1", last: "baasdasdr", email: "[email protected]", created_at: "2010-12-30 17:20:49", updated_at: "2010-12-30 17:20:49">]

Например, первый элемент в этом массиве показывает одного пользователя с «foo» и «[email protected]». Остальные их можно вытаскивать из базы по мере надобности при находке.

> User.find(:all, :conditions => {:email => "[email protected]", :first => "foo"})
 => [#<User id: 1, first: "foo", last: "bar", email: "[email protected]", created_at: "2010-12-30 17:14:28", updated_at: "2010-12-30 17:14:28">, 
     #<User id: 3, first: "foo", last: "barney", email: "[email protected]", created_at: "2010-12-30 17:14:43", updated_at: "2010-12-30 17:14:43">]

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

Изменить:

Если вам нужно использовать большой молот find_by_sql, поскольку Rails 2.2 и более ранние версии не поддерживали :having с find, следующее должно сработать и дать вам тот же массив, который я описал выше.

User.find_by_sql("select * from users group by first,email having count(*) > 1")
30.12.2010
  • Мне нравится ваш ответ, но он только для рельсов 2.3 и выше, а приложение 2.2. 30.12.2010
  • Хм, странно. Клянусь, я использую :having уже много лет, но, возможно, у меня произошло короткое замыкание в памяти. Возможно, вам придется прибегнуть к использованию find_by_sql и ручному созданию группы / наличия предложений, но я тоже немного покопаюсь для вас. api.rubyonrails.org/classes/ActiveRecord/ 30.12.2010
  • Это как раз то, что мне нужно. Как бы вы сделали это в монгоиде? Вы не можете использовать группу в mongoid, и я не думаю, что вы можете использовать их. Надеюсь, вы сможете вести меня в правильном направлении. 24.05.2012
  • Не будет работать в Postgres для меня: - PG::GroupingError: ОШИБКА: столбец user.id должен отображаться в предложении GROUP BY или использоваться в агрегатной функции, но поскольку нет двух записей с одинаковым идентификатором, в том числе это приведет к поражению цель. Или, может быть, я просто не понимаю, что означает в данном контексте или быть использованным в агрегатной функции. 26.05.2015
  • Вы пытаетесь использовать один из запросов выше или это ваш собственный? Имейте в виду, что этому ответу уже 5 лет и 2 основные версии Rails. 27.05.2015

  • 2

    После некоторого гугления я пришел к следующему:

    ActiveRecord::Base.connection.execute(<<-SQL).to_a
      SELECT 
        variants.id, variants.variant_no, variants.state 
      FROM variants INNER JOIN (
        SELECT 
          variant_no, state, COUNT(1) AS count 
        FROM variants
        GROUP BY 
          variant_no, state HAVING COUNT(1) > 1
      ) tt ON 
        variants.variant_no = tt.variant_no 
        AND variants.state IS NOT DISTINCT FROM tt.state;
    SQL
    

    Обратите внимание на ту часть, которая говорит IS NOT DISTINCT FROM, чтобы помочь справиться со значениями NULL, которые нельзя сравнивать со знаком равенства в postgres.

    23.06.2015
  • Что делать, если вы хотите вернуть идентификаторы дубликатов записей? Ответ в сообщении SO, на которое вы ссылаетесь, просто возвращает имена/адреса электронной почты, в которых есть дубликаты... в идеале я бы вернул массив массивов, каждый массив, содержащий идентификаторы одной повторяющейся группы. 24.06.2015
  • Да, в итоге я использовал пользовательский SQL. 24.06.2015

  • 3

    Если вы идете по пути @hakunin и создаете запрос вручную, вы можете использовать следующее:

    ActiveRecord::Base.connection.exec_quey(<<-SQL).to_a
      SELECT 
        variants.id, variants.variant_no, variants.state 
      FROM variants INNER JOIN (
        SELECT 
          variant_no, state, COUNT(1) AS count 
        FROM variants
        GROUP BY 
          variant_no, state HAVING COUNT(1) > 1
      ) tt ON 
        variants.variant_no = tt.variant_no 
        AND variants.state IS NOT DISTINCT FROM tt.state;
    SQL
    

    Изменение заключается в замене connection.execute(<<-SQL) на connection.exec_query(<<-SQL).

    Может быть проблема с утечкой памяти при использовании execute

    Пожалуйста, прочтите Clarify DataBaseStatements#execute, чтобы получить более полное представление о проблеме.

    11.05.2017
    Новые материалы

    Интуитивное понимание тензоров в машинном обучении
    Тензор является важной концепцией во многих научных областях, таких как математика, физика, обработка сигналов и компьютерное зрение, и это лишь некоторые из них. В математике тензор — это..

    Использование машинного обучения для диагностики болезни Альцгеймера, часть 4
    Маркеры семантической согласованности для ранней диагностики болезни Альцгеймера (arXiv) Автор: Давиде Колла , Маттео Дельсанто , Марко Агосто , Бенедетто Витиелло , Даниэле Паоло Радичони..

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

    Анимированный математический анализ
    Использование Manim для создания математических анимированных визуализаций Визуализация данных помогает понять скрытые закономерности в данных, которые невозможно визуализировать..

    Создание простого слайдера изображений с помощью JavaScript
    Узнайте, как создать базовый слайдер изображений с помощью HTML, CSS и JavaScript. Введение В этом уроке мы создадим удобный слайдер изображений, используя JavaScript, HTML и CSS. Ползунок..

    Создание базы данных с помощью супергероя «Python»
    В этом посте мы узнаем, как создать «базу данных SQLite с помощью модуля python sqlite3, создав простую функцию входа и регистрации. Готовы ли вы к этому путешествию? Если да , давайте приступим..

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