Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737 Форумы портала PHP.SU :: Вариации данных в массиве
Покинул форум
Сообщений всего: 94
Дата рег-ции: Июль 2010
Помог: 0 раз(а)
Доброго времени суток.
Поступила задачка отыскать в базе данных пользователей записи, пытаясь найти все совпадения. Знаю что прозвучало это слегка "загадочно", потому попросту перейду к примеру:
Человек пытается найти запись: Карлов Иван Исаакович
Вводя это в строку поиска, система получает одну целую строку, разбивает её элементы массива, ориентируясь на пробел, все лишние элементы отсекает, и пытается найти всевозможные вариации строки Карлов Иван Исаакович, а именно:
Карлов Иван Исаакович
Иван Карлов Исаакович
Исаакович Иван Карлов
Карлов Иван
Иван Карлов
...
Исаакович
...
Разбить массив на элементы, отсечь лишнее и вручную вписать все вариации запросов к БД, ориентируясь на первоначальное к-во элементов(допустим их не 3 а 2 или 1), конечно можно, но хотелось бы услышать ответ на вопрос: Можно ли както автоматизировать процесс перебора элементов массива?
Покинул форум
Сообщений всего: 2132
Дата рег-ции: Дек. 2008 Откуда: Москваль
Помог: 52 раз(а)
Я бы хранил ключ, который был бы md5 от отсортированных ФИО и искал по ним, не ?
скажем так:
Иванов
Акакий
Валерьевич
приводилось бы к md5(АкакийВалерьевичИванов) и сохранялось
Яковлев
Шамиль
Арсеньевич
приводилось бы к md5(АрсеньевичШамильЯковлев)
и тд
Это если решать вашу задачу в лоб, а так можно и над более элегантным решением подумать ... к чему это я? К тому, что у вас задача первоначально немного иная - найти совпадения, может быть решена более простым и быстрым вариантом (Добавление)
разбить строку в массив http://ru.php.net/manual/en/function.explode.php
пройтись по массиву foeach()
Ну или регулярки
SunChase
Отправлено: 10 Ноября, 2011 - 17:39:08
Гость
Покинул форум
Сообщений всего: 94
Дата рег-ции: Июль 2010
Помог: 0 раз(а)
foreach если не ошибаюсь ориентирован на каждый элемент массива в отдельности, и будет иметь к-во циклов, равное к-ву элементов массива(поправьте, если неправ), тобиш 3. Тут же из 3х элементов получается как минимум 14 вариантов...
Конечно можно воспользоваться foreach и применить для поиска каждый элемент в роле Фамилии, Имя или Отчества, но это будет иметь меньшую точность...
WHERE f1 LIKE'%фыва%'OR f2 LIKE'%фыва%'OR... fN LIKE'%фыва%'
Количество полей известно заранее и равно трем.
Задача не тривиальна..
Если искать по трем словам, то к каждому полю всего три варианта LIKE..
А чтобы не искали по длинным словам, резать их, а чтобы не искали по 10 словам (такое только гугл себе позволить может), ограничиваться максимум, скажем, четырьмя первыми. (Добавление)
Еще есть оч хорошая штука - FULLTEXT
Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007 Откуда: Berlin
Помог: 707 раз(а)
А если есть
Петр Иванов
Сидор Петрович
Федор Иванов
- то по запросу "Петр Иванов" - рано или поздно будет поиск просто по "Иванов" и "Петр".
Так вот, в первом случае - должна ли система найти "Федор Иванов" а во втором - "Сидор Петрович"?
----- Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
SunChase
Отправлено: 10 Ноября, 2011 - 18:10:26
Гость
Покинул форум
Сообщений всего: 94
Дата рег-ции: Июль 2010
Помог: 0 раз(а)
А в том то и дело, что в случае:
f1 like "%bla1%" or f2 like "%bla2%" or f3 like "%bla3%"
я получу "рулон", где хотябы одно из like подошло по условию, то есть на запрос Петя Васячкин Иванов, я получу на кучу всех Васячкинов,Ивановов и Петь. У меня же задача лежит "выловить" всё, постепенно отделяя по одному элементу из массива, тобиш:
f1 like "%bla1%" and f2 like "%bla2" and f3 like "%bla3"
....
f1 like "%bla3%" and f2 like "%bla1%"
...
тоесть сначала я получу все доступные записи по Пети Васячкине Иванове во всех вариациях, потом по Пети Васячкине и т.д.
DeepVarvar
Отправлено: 10 Ноября, 2011 - 18:18:15
Активный участник
Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008 Откуда: Альфа Центавра
Покинул форум
Сообщений всего: 94
Дата рег-ции: Июль 2010
Помог: 0 раз(а)
DeepVarvar пишет:
И сколько запросов делать намерены?
Знаю, что делать 14 запросов ради того, чтобы отыскать человека, маленько попахивает "бредовостью", но интереса ради хотелось бы увидеть как вообще можно реализовать поставленную задачу
DeepVarvar
Отправлено: 10 Ноября, 2011 - 18:38:00
Активный участник
Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008 Откуда: Альфа Центавра
Покинул форум
Сообщений всего: 2132
Дата рег-ции: Дек. 2008 Откуда: Москваль
Помог: 52 раз(а)
Аааа, ясно что вы хотите
вам нужен snowball stemming algorithm. разбор на слова, приведение к словоформам и индексация в отдельной таблице. Когда вам нужно будет найти - выгребаете все, куда ведет хотя бы 1 из слов и сортируется по количеству упоминаний в выборке. Более продвинутые алгоритмы ранжирования будут излишне
tuareg
Отправлено: 10 Ноября, 2011 - 19:54:57
Участник
Покинул форум
Сообщений всего: 1234
Дата рег-ции: Июнь 2010
Помог: 69 раз(а)
Добавьте три поля типа int(11)
И при сохранении делайте поле1=CRS32('поле1') поле2=CRS32('поле2')и т.д
Тогда запрос будет при трех параметрах
И уже потом PHP фильтруем как надо.
LIKE долго и не оптимально, здесь плюс используем индекс
Да и еще по условию(топик читал, но не викал) если точно знаем что вводятся 3 значения но не знаем порядок тогда просто добавляем одно поле int(11) при сохранении делаем CRS32('вся строка') и при запросе будет просто перебор возможных вариантов
Покинул форум
Сообщений всего: 94
Дата рег-ции: Июль 2010
Помог: 0 раз(а)
сделал вариации условия поиска согласно к-ву слов(не стал вдаваться в подробности с уменьшением к-ва элементов). Вроде бы всё нормально находит. Всем спасибо за информацию
Все гости форума могут просматривать этот раздел. Только зарегистрированные пользователи могут создавать новые темы в этом разделе. Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.