Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / MySQL Новый топик    Ответить
Топик располагается на нескольких страницах: 1 2      [все]
 FAQ: обработка строк и парсинг текстов средствами MySQL  [new]
Arhat109
Member

Откуда: из СССР
Сообщений: 3282
ну вот ... прошло 2 года с тех пор как занялся прсингом текстов силами Мускуля ... предлагаю организовать ФАК по работе с текстами и особенностях применения Locate(), Replace(), Find_in_set(), Substring_index() и прочих прелестей...

Для начала:

Запрос "разбивка текстового поля на слова по пробелу" (первые 10 слов):

  SELECT
    tmp.`id` AS `num`
    , SUBSTRING_INDEX(SUBSTRING_INDEX(src.`text_field`, ' ', tmp.`id`), ' ', -1) AS `word`
    , src.`text_field` AS source
  FROM (
    SELECT 1 AS num UNION ALL
    SELECT 2 UNION ALL
    SELECT 3 UNION ALL
    SELECT 4 UNION ALL
    SELECT 5 UNION ALL
    SELECT 6 UNION ALL
    SELECT 7 UNION ALL
    SELECT 8 UNION ALL
    SELECT 9 UNION ALL
    SELECT 10 UNION ALL
  ) AS tmp
  JOIN `text_table` AS src
  HAVING `word` <> ''


При необходимости можно заменить пробел чем-то другим - просто заменив вхождения его в обе функции как строки-разделителя.
При необходимости можно создать отдельную табличку с чиселками и джойниться к ней и находить и большее количество слов или джойнить две таких группы для поиска до сотни слов или три для поиска до тысячи слов или ... :)

Недостаток запроса - он выдает всегда то количество слов, скока цифирек сджойнено, и, если слов меньше - тупо повторяет последнее слово... как "поправить" - предлагаю дополнить после выделения темы.

... продолжение "типовых" запросов по текстовой обработке для начинающих - привествуется.
26 ноя 14, 18:01    [16909873]     Ответить | Цитировать Сообщить модератору
 Re: FAQ: обработка строк и парсинг текстов средствами MySQL  [new]
javajdbc
Member

Откуда: Montreal
Сообщений: 17123
Arhat109,

да, хороший вариант. Он уже представлен
по ссылке прямо в предыдушем посте 13640230,
там показан полный пример со джоинтом и
сравнение с другими способами решения.
26 ноя 14, 18:12    [16909924]     Ответить | Цитировать Сообщить модератору
 Re: FAQ: обработка строк и парсинг текстов средствами MySQL  [new]
miksoft
Member

Откуда:
Сообщений: 36323
Arhat109
ну вот ... прошло 2 года с тех пор как занялся прсингом текстов силами Мускуля ... предлагаю организовать ФАК по работе с текстами и особенностях применения Locate(), Replace(), Find_in_set(), Substring_index() и прочих прелестей...
В целом я только за!
Возьметесь написать стартовый пост?

P.S. Хотя сам парсинг силами MySQL мне кажется весьма неэффективным по скорости и ресурсам.

Arhat109
Недостаток запроса - он выдает всегда то количество слов, скока цифирек сджойнено, и, если слов меньше - тупо повторяет последнее слово... как "поправить" - предлагаю дополнить после выделения темы.
А если в конец строки добить 9 пробелов?

Arhat109
... продолжение "типовых" запросов по текстовой обработке для начинающих - привествуется.
15921841 годится? буквально вчера было...
26 ноя 14, 18:13    [16909928]     Ответить | Цитировать Сообщить модератору
 Re: FAQ: обработка строк и парсинг текстов средствами MySQL  [new]
Arhat109
Member

Откуда: из СССР
Сообщений: 3282
javajdbc,

ну ... ваш запрос оригинален (снимаю шляпу :) ) и кажется вполне рабочим, но как понимаю применим к конкретной задаче хранения листьев в деревьях всеж-таки (как не надо делать).

Я имел ввиду общую обработку текстов силами Мускуля.

Например, часто требуется найти "похожие" строки, по алгоритму, отличному от full text search ... и народ часто решает вопрос путем выкачки данных в приложение и ваяет циклы на ЯП (С, PHP, кто на чем горазд).

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

Озадачился что тут нет такого фака, поскольку потерял свой запрос по разбивке товарной строки на слова, по заданному набору разделителей ("по или", а не одному!) из вспомогательной таблички с поиском полученных слов в словаре Зализняка и получением результата в виде:

порядок, слово, часть_речи (если найдена).

:)
26 ноя 14, 18:45    [16910018]     Ответить | Цитировать Сообщить модератору
 Re: FAQ: обработка строк и парсинг текстов средствами MySQL  [new]
Arhat109
Member

Откуда: из СССР
Сообщений: 3282
miksoft,

Предлагаю вынести мой пост в отдельный ФАК "для начала", а потом усложнять запрос постепенно до вменяемого результата. :)

Вряд ли сподоблюсь написать целую статью ... ни умею. :)

Я делал ограничение через переменные: как только "предыдущее" слово равно "новому" - значит "кончились". :)
26 ноя 14, 18:57    [16910061]     Ответить | Цитировать Сообщить модератору
 Re: FAQ: обработка строк и парсинг текстов средствами MySQL  [new]
miksoft
Member

Откуда:
Сообщений: 36323
Arhat109
словарь Зализняка
Из одного этого только словосочетания нужно сделать, как минимум, отдельный пост. А то и топик! :)
26 ноя 14, 18:59    [16910071]     Ответить | Цитировать Сообщить модератору
 Re: FAQ: обработка строк и парсинг текстов средствами MySQL  [new]
miksoft
Member

Откуда:
Сообщений: 36323
Arhat109
Я делал ограничение через переменные: как только "предыдущее" слово равно "новому" - значит "кончились". :)
А если по факту будут одинаковые слова? Да еще в середине строки?
(У меня реально встречается, что одно слово в наименовании товара встречается даже трижды).
26 ноя 14, 19:02    [16910074]     Ответить | Цитировать Сообщить модератору
 Re: FAQ: обработка строк и парсинг текстов средствами MySQL  [new]
miksoft
Member

Откуда:
Сообщений: 36323
Arhat109
Предлагаю вынести мой пост в отдельный ФАК "для начала", а потом усложнять запрос постепенно до вменяемого результата. :)
Выделил.
26 ноя 14, 19:12    [16910109]     Ответить | Цитировать Сообщить модератору
 Re: FAQ: обработка строк и парсинг текстов средствами MySQL  [new]
Arhat109
Member

Откуда: из СССР
Сообщений: 3282
miksoft, Упс. Не было такого... да, тогда это работать будет некорректно:

SELECT
    tmp.`id` AS `num`
    , IF( @old <> (@new:=SUBSTRING_INDEX(SUBSTRING_INDEX(src.`text_field`, ' ', tmp.`id`), ' ', -1))
      , @old:=@new
      , ''
    ) AS `word`
    , src.`text_field` AS source
  FROM
  (SELECT @old:=@new:='') AS dummy
  ,(SELECT 1 AS num UNION ALL
    SELECT 2 UNION ALL
    SELECT 3 UNION ALL
    SELECT 4 UNION ALL
    SELECT 5 UNION ALL
    SELECT 6 UNION ALL
    SELECT 7 UNION ALL
    SELECT 8 UNION ALL
    SELECT 9 UNION ALL
    SELECT 10 UNION ALL
  ) AS tmp
  , `text_table` AS src
  HAVING `word` <> ''


точнее он отдаст все одинаковые слова ровно по одному разу... :)
26 ноя 14, 19:32    [16910189]     Ответить | Цитировать Сообщить модератору
 Re: FAQ: обработка строк и парсинг текстов средствами MySQL  [new]
Arhat109
Member

Откуда: из СССР
Сообщений: 3282
Arhat109,

уточнение: "все одинаковые слова, стоящие подряд". Если они перемежаются другими словами, то выдаст "как надо". :)
26 ноя 14, 19:36    [16910212]     Ответить | Цитировать Сообщить модератору
 Re: FAQ: обработка строк и парсинг текстов средствами MySQL  [new]
miksoft
Member

Откуда:
Сообщений: 36323
Arhat109
точнее он отдаст все одинаковые слова ровно по одному разу... :)
Еще точнее - сократит одинаковые слова, идущие подряд в порядке чисел в результате подзапроса tmp, который внезапно может измениться, особенно если использовать настоящую таблицу.
26 ноя 14, 19:39    [16910232]     Ответить | Цитировать Сообщить модератору
 Re: FAQ: обработка строк и парсинг текстов средствами MySQL  [new]
miksoft
Member

Откуда:
Сообщений: 36323
Arhat109
Arhat109,

уточнение: "все одинаковые слова, стоящие подряд". Если они перемежаются другими словами, то выдаст "как надо". :)
я опоздал с уточнением :)
26 ноя 14, 19:39    [16910236]     Ответить | Цитировать Сообщить модератору
 Re: FAQ: обработка строк и парсинг текстов средствами MySQL  [new]
Arhat109
Member

Откуда: из СССР
Сообщений: 3282
Вот такой вариант неожиданно, но работает верно (MySql 5.1.67? не помню какой стоит...)

SELECT
    tmp.`id` AS `num`
    , SUBSTRING_INDEX(@new:=SUBSTRING_INDEX(src.`text_field`, ' ', tmp.`id`), ' ', -1) AS `word`
    , src.`text_field` AS source
  FROM
  (SELECT @new:='') AS dummy
  ,(SELECT 1 AS num UNION ALL
    SELECT 2 UNION ALL
    SELECT 3 UNION ALL
    SELECT 4 UNION ALL
    SELECT 5 UNION ALL
    SELECT 6 UNION ALL
    SELECT 7 UNION ALL
    SELECT 8 UNION ALL
    SELECT 9 UNION ALL
    SELECT 10 UNION ALL
  ) AS tmp
  , `text_table` AS src
  WHERE CHAR_LENGTH(@new) < CHAR_LENGTH(src.`text_field`)


, хотя "по идее" должен глотать последнее слово...
26 ноя 14, 20:23    [16910375]     Ответить | Цитировать Сообщить модератору
 Re: FAQ: обработка строк и парсинг текстов средствами MySQL  [new]
Arhat109
Member

Откуда: из СССР
Сообщений: 3282
Разобрался. Работает верно, потому что блок проверки WHERE обрабатывается ранее блока выборки SELECT в силу оптимизации выполнения запроса. Логично, но не уверен что можно рекомендовать в ФАК.
27 ноя 14, 06:50    [16911642]     Ответить | Цитировать Сообщить модератору
 Re: FAQ: обработка строк и парсинг текстов средствами MySQL  [new]
javajdbc
Member

Откуда: Montreal
Сообщений: 17123
Arhat109
Разобрался. Работает верно, потому что блок проверки WHERE обрабатывается ранее блока выборки SELECT в силу оптимизации выполнения запроса. Логично, но не уверен что можно рекомендовать в ФАК.



...это извесное правило: применение переменных в WHERE
категорически запрешено всем кроме Бочкова.
27 ноя 14, 07:10    [16911654]     Ответить | Цитировать Сообщить модератору
 Re: FAQ: обработка строк и парсинг текстов средствами MySQL  [new]
Arhat109
Member

Откуда: из СССР
Сообщений: 3282
javajdbc, использовать можно. Изменять нельзя. :)

Продолжаем. Наткнулся на вот это обсуждение: 16690327 по вопросу построения "сочинителя сказок" силами Мускуля, как понял задачу. Думаю дать ссылку тут - будет полезно.
27 ноя 14, 08:39    [16911743]     Ответить | Цитировать Сообщить модератору
 Re: FAQ: обработка строк и парсинг текстов средствами MySQL  [new]
Arhat109
Member

Откуда: из СССР
Сообщений: 3282
Задача2: обрезать последнее слово в строке:

TRIM(TRAILING SUBSTRING_INDEX(#string#, #pattern#, -1) FROM #string#)

обсуждение тут: 15548673
27 ноя 14, 09:11    [16911856]     Ответить | Цитировать Сообщить модератору
 Re: FAQ: обработка строк и парсинг текстов средствами MySQL  [new]
Arhat109
Member

Откуда: из СССР
Сообщений: 3282
miksoft
Arhat109
словарь Зализняка
Из одного этого только словосочетания нужно сделать, как минимум, отдельный пост. А то и топик! :)


нашел. Начало было тут: 13369064
27 ноя 14, 09:51    [16912031]     Ответить | Цитировать Сообщить модератору
 Re: FAQ: обработка строк и парсинг текстов средствами MySQL  [new]
Arhat109
Member

Откуда: из СССР
Сообщений: 3282
Продолжаем сбор "полезностей" по работе с текстами. Нашел вот это:

Есть таблица с полем `name`. В поле хранятся записи вида А. Пупкин, А. В. Бубликов и т.д. Проблема в том, что сортировать их нужно по фамилии, а потом по инициалам. Хранить имя, отчество и фамилию в разных полях или в другом порядке - не вариант, нужно работать с полем такого вида. В результате непродолжительных раздумий, родил запрос вида

SELECT ... ORDER BY SUBSTR(`name`, - (LOCATE('.', REVERSE(`name`)) - 2)), `name`;


Взято тут 12800557
27 ноя 14, 10:13    [16912113]     Ответить | Цитировать Сообщить модератору
 Re: FAQ: обработка строк и парсинг текстов средствами MySQL  [new]
javajdbc
Member

Откуда: Montreal
Сообщений: 17123
Arhat109
javajdbc, использовать можно. Изменять нельзя. :)



В обшем виде -- НЕЛЬЗЯ.

Попробуем классифицировать контекстЫ
для переменных. Нужна стабильность и предсказуемость.

1-1. Стабильно. Порядок вычисления внутри функций:
Например, LEAST(A, B, C) всегда вычисляется слева направо.

1-2. Стабильно. Порядок вычисления строчек в SELECT блоке
при наличии ORDER BY и отсутствии GROUP BY. Если есть ГРОУП БУ
то надо вынести ORDER BY в окружной селект.

2. Недокументировано, но стабильно. Порядок вычисления полей
в SELECT блоке. Т.е. SELECT A, B, C FROM... вычисляет
A, B, C в указаном порядке. Стандарты СКЛ и MYSQL документация
никак не прописывают порядок. Однако я не видел ни одного
отрицательного примера.

Параноикам советуется использование способа (1-1) вместо (2).

3-1. Нестабильно. порядок выполнения вычислений в WHERE и JOIN ON блоке.
В литературе в ЯВНОМ виде показано как ломаются вычисления с переменными.
Из-за того что порядок зависит от плана.
Из-за того что план зависит от статистики, индексов и фазы луны.

3-2. Нестабильно. Использовать переменные в SELЕCT и WHERE блоках
одновремено. Во-первых (3), во вторых даже если в WHERE
только читать переменную, все равно не доказан строгий ход
вычислений между двумя блоками.

В целом -- мускл переменные -- полезная но капризная штука.
Попытки использования переменных в "нестабильном" контексте
приводит к "нестабильным" результатам.
27 ноя 14, 17:44    [16915316]     Ответить | Цитировать Сообщить модератору
 Re: FAQ: обработка строк и парсинг текстов средствами MySQL  [new]
Arhat109
Member

Откуда: из СССР
Сообщений: 3282
javajdbc, согласен. В целом, переменные в запросе - это не совсем скуль где-то даже... но, многое что можно сделать в части парсинга текстов - без них, увы силами "чистого sql", возможно и не решаемо совсем.

В частности, разбивка строки на слова не по пробелу или другому одиночному символу, а по заданному набору разделителей - как?

Пример:

Альб д/рис,40л.,картон-А4,"Алые Паруса"

надо получить:
Альб -- вид товара
д/рис -- подвид товара
40л. -- параметр "количество листов"
картон -- параметр "материал обложки"
А4 -- параметр "формат"
"Алые Паруса" -- параметр "картинка на обложке"

Разделители: пробел, запятая, тире.
27 ноя 14, 19:27    [16915767]     Ответить | Цитировать Сообщить модератору
 Re: FAQ: обработка строк и парсинг текстов средствами MySQL  [new]
javajdbc
Member

Откуда: Montreal
Сообщений: 17123
Arhat109,

Ну с разделителями -- достаточно просто :
свести все разделители к одному путем
нескольких замен -- пробел на запятую,
точку на запятую....
а потом разбивать по запятой как мы уже знаем...
27 ноя 14, 19:38    [16915807]     Ответить | Цитировать Сообщить модератору
 Re: FAQ: обработка строк и парсинг текстов средствами MySQL  [new]
Arhat109
Member

Откуда: из СССР
Сообщений: 3282
javajdbc,

Можно. Предположим что список разделителей лежит в табличке. Запрос, который делает замену в строке одной таблички по набору записей образцов из другой - приведете? (потом усложню задачу) :)
28 ноя 14, 08:14    [16917010]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: FAQ: обработка строк и парсинг текстов средствами MySQL  [new]
blogger1988
Member

Откуда: Нижний Новгород
Сообщений: 1
Arhat109,
все одинаковые слова, стоящие подряд". Если они перемежаются другими словами, то выдаст "как надо". :)
17 мар 16, 23:39    [18945997]     Ответить | Цитировать Сообщить модератору
 Re: FAQ: обработка строк и парсинг текстов средствами MySQL  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 33438
Arhat109,

этот весь топик - извращение какое-то,
разбирать текст надо не на SQL, для этого полно средств от строковых функций и регулярных выражений до компиляторов и их генераторов.
20 мар 16, 08:55    [18954808]     Ответить | Цитировать Сообщить модератору
 Re: FAQ: обработка строк и парсинг текстов средствами MySQL  [new]
вадя
Member

Откуда: Екатеринбург
Сообщений: 12726
эту конструкцию
SELECT 1 AS num UNION ALL
    SELECT 2 UNION ALL
    SELECT 3 UNION ALL
    SELECT 4 UNION ALL
    SELECT 5 UNION ALL
    SELECT 6 UNION ALL
    SELECT 7 UNION ALL
    SELECT 8 UNION ALL
    SELECT 9 UNION ALL
    SELECT 10 UNION ALL


можно заменить на
SET @d = 0;
SELECT
  @d := @d+1 AS d
FROM любая_таблица
WHERE @d < 10
5 май 16, 05:22    [19136394]     Ответить | Цитировать Сообщить модератору
 Re: FAQ: обработка строк и парсинг текстов средствами MySQL  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 15944
Это хорошо, когда есть под рукой "любая таблица" с достаточным количеством записей... а то к INFORMATION_SCHEMA придётся обращаться - как бы некрасиво...
5 май 16, 10:29    [19137011]     Ответить | Цитировать Сообщить модератору
 Re: FAQ: обработка строк и парсинг текстов средствами MySQL  [new]
paha4444
Member

Откуда: Украина Одесская обл., Рени
Сообщений: 69
MasterZiv,

100% жесть полная! Интересно, если БД огромная то сколько займут времени такие запросы....
8 окт 16, 08:58    [19758447]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: 1 2      [все]
Все форумы / MySQL Ответить